refactor: 拆分 WarehouseService 的 Create/Update,去掉 ID==0 猜分支
This commit is contained in:
parent
16ca9c02ba
commit
6ed205dcb8
|
|
@ -349,7 +349,7 @@ func (h *Handler) CreateWarehouse(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item.OrganizationID = orgID
|
item.OrganizationID = orgID
|
||||||
if err := h.warehouseSvc.Save(&item); err != nil {
|
if err := h.warehouseSvc.Create(&item); err != nil {
|
||||||
response.BadRequest(c, err.Error())
|
response.BadRequest(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -369,7 +369,7 @@ func (h *Handler) UpdateWarehouse(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item.ID, item.OrganizationID = id, orgID
|
item.ID, item.OrganizationID = id, orgID
|
||||||
if err := h.warehouseSvc.Save(&item); err != nil {
|
if err := h.warehouseSvc.Update(&item); err != nil {
|
||||||
response.BadRequest(c, err.Error())
|
response.BadRequest(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -389,7 +389,7 @@ func (h *Handler) CreateWarehouseLocation(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item.WarehouseID = warehouseID
|
item.WarehouseID = warehouseID
|
||||||
if err := h.warehouseSvc.SaveLocation(&item, orgID); err != nil {
|
if err := h.warehouseSvc.CreateLocation(&item, orgID); err != nil {
|
||||||
response.BadRequest(c, err.Error())
|
response.BadRequest(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -414,7 +414,7 @@ func (h *Handler) UpdateWarehouseLocation(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item.ID, item.WarehouseID = locationID, warehouseID
|
item.ID, item.WarehouseID = locationID, warehouseID
|
||||||
if err := h.warehouseSvc.SaveLocation(&item, orgID); err != nil {
|
if err := h.warehouseSvc.UpdateLocation(&item, orgID); err != nil {
|
||||||
response.BadRequest(c, err.Error())
|
response.BadRequest(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,27 @@ func NewWarehouseService() *WarehouseService {
|
||||||
func (s *WarehouseService) List(orgID int64) ([]model.Warehouse, error) {
|
func (s *WarehouseService) List(orgID int64) ([]model.Warehouse, error) {
|
||||||
return s.repo.List(orgID)
|
return s.repo.List(orgID)
|
||||||
}
|
}
|
||||||
func (s *WarehouseService) Save(item *model.Warehouse) error {
|
// Create 新建仓库。不读取 item.ID,脏 id 不会把新建变成覆盖。
|
||||||
|
func (s *WarehouseService) Create(item *model.Warehouse) error {
|
||||||
|
if err := prepareWarehouse(item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return s.repo.Create(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update 更新仓库。id 来自路由参数,必须显式存在。
|
||||||
|
func (s *WarehouseService) Update(item *model.Warehouse) error {
|
||||||
|
if item.ID == 0 {
|
||||||
|
return errUpdateRequiresID
|
||||||
|
}
|
||||||
|
if err := prepareWarehouse(item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return s.repo.Update(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepareWarehouse 是新建与更新共用的字段清理、校验和默认值补全。
|
||||||
|
func prepareWarehouse(item *model.Warehouse) error {
|
||||||
item.Code = strings.TrimSpace(item.Code)
|
item.Code = strings.TrimSpace(item.Code)
|
||||||
item.Name = strings.TrimSpace(item.Name)
|
item.Name = strings.TrimSpace(item.Name)
|
||||||
if item.Code == "" || item.Name == "" {
|
if item.Code == "" || item.Name == "" {
|
||||||
|
|
@ -260,12 +280,30 @@ func (s *WarehouseService) Save(item *model.Warehouse) error {
|
||||||
if item.Status == "" {
|
if item.Status == "" {
|
||||||
item.Status = "active"
|
item.Status = "active"
|
||||||
}
|
}
|
||||||
if item.ID == 0 {
|
return nil
|
||||||
return s.repo.Create(item)
|
|
||||||
}
|
|
||||||
return s.repo.Update(item)
|
|
||||||
}
|
}
|
||||||
func (s *WarehouseService) SaveLocation(item *model.WarehouseLocation, orgID int64) error {
|
|
||||||
|
// CreateLocation 新建库位。orgID 用于校验仓库归属,item.ID 不参与。
|
||||||
|
func (s *WarehouseService) CreateLocation(item *model.WarehouseLocation, orgID int64) error {
|
||||||
|
if err := prepareLocation(item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return s.repo.CreateLocation(item, orgID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateLocation 更新库位。id 来自路由参数,必须显式存在。
|
||||||
|
func (s *WarehouseService) UpdateLocation(item *model.WarehouseLocation, orgID int64) error {
|
||||||
|
if item.ID == 0 {
|
||||||
|
return errUpdateRequiresID
|
||||||
|
}
|
||||||
|
if err := prepareLocation(item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return s.repo.UpdateLocation(item, orgID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepareLocation 是新建与更新共用的字段清理、校验和默认值补全。
|
||||||
|
func prepareLocation(item *model.WarehouseLocation) error {
|
||||||
item.Code = strings.TrimSpace(item.Code)
|
item.Code = strings.TrimSpace(item.Code)
|
||||||
item.Name = strings.TrimSpace(item.Name)
|
item.Name = strings.TrimSpace(item.Name)
|
||||||
if item.Code == "" || item.Name == "" || item.WarehouseID <= 0 {
|
if item.Code == "" || item.Name == "" || item.WarehouseID <= 0 {
|
||||||
|
|
@ -274,8 +312,5 @@ func (s *WarehouseService) SaveLocation(item *model.WarehouseLocation, orgID int
|
||||||
if item.Status == "" {
|
if item.Status == "" {
|
||||||
item.Status = "active"
|
item.Status = "active"
|
||||||
}
|
}
|
||||||
if item.ID == 0 {
|
return nil
|
||||||
return s.repo.CreateLocation(item, orgID)
|
|
||||||
}
|
|
||||||
return s.repo.UpdateLocation(item, orgID)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,3 +98,36 @@ func TestUnitCreateStillValidatesPrecisionScale(t *testing.T) {
|
||||||
t.Fatal("precision_scale 超过 6 应当被拒绝")
|
t.Fatal("precision_scale 超过 6 应当被拒绝")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWarehouseCreateInsertsEvenWhenItemCarriesStaleID(t *testing.T) {
|
||||||
|
db, mock, err := sqlmock.New()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("sqlmock: %v", err)
|
||||||
|
}
|
||||||
|
database.DB = db
|
||||||
|
t.Cleanup(func() { database.DB = nil; db.Close() })
|
||||||
|
|
||||||
|
mock.ExpectExec("INSERT INTO warehouses").WillReturnResult(sqlmock.NewResult(5, 1))
|
||||||
|
|
||||||
|
item := &model.Warehouse{ID: 3, Code: "WH2", Name: "二号仓"}
|
||||||
|
if err := NewWarehouseService().Create(item); err != nil {
|
||||||
|
t.Fatalf("Create: %v", err)
|
||||||
|
}
|
||||||
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||||||
|
t.Fatalf("应当执行 INSERT,实际 SQL 不是插入: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWarehouseUpdateRequiresID(t *testing.T) {
|
||||||
|
err := NewWarehouseService().Update(&model.Warehouse{Code: "WH1", Name: "一号仓"})
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("缺少 id 的更新应当被拒绝")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLocationCreateRequiresWarehouseID(t *testing.T) {
|
||||||
|
err := NewWarehouseService().CreateLocation(&model.WarehouseLocation{Code: "L1", Name: "库位一"}, 1)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("缺少 warehouse_id 的库位创建应当被拒绝")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user