zhangqian
2024-06-14 72b4fcd52bd82427b3932a5a5c01ced2c0dee201
finish operation code refactor
1个文件已添加
5个文件已修改
531 ■■■■ 已修改文件
conf/config.yaml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
controllers/operation.go 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/location_product_amount.go 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/operation.go 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/move_history.go 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/operation.go 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
conf/config.yaml
@@ -11,7 +11,7 @@
  companyName: jialian
db:
  #  dsn: root:c++java123@tcp(192.168.20.119:3306)/wms?charset=utf8&parseTime=True&loc=Local
  dsn: root:c++java123@tcp(192.168.20.119:3306)/aps_server2?charset=utf8&parseTime=True&loc=Local
  dsn: root:c++java123@tcp(127.0.0.1:3306)/aps_server2?charset=utf8&parseTime=True&loc=Local
  logMode: true
  maxIdleCon: 20
  maxOpenCon: 100
controllers/operation.go
@@ -3,7 +3,6 @@
import (
    "context"
    "errors"
    "fmt"
    "github.com/gin-gonic/gin"
    uuid "github.com/satori/go.uuid"
    "github.com/shopspring/decimal"
@@ -435,231 +434,38 @@
        }
    }
    userInfo := middleware.GetUserInfo(c)
    err = models.WithTransaction(func(tx *gorm.DB) error {
        if err := models.NewOperationSearch().SetOrm(tx).SetID(id).Update(&models.Operation{
            Status:    constvar.OperationStatus_Finish,
            CheckedBy: userInfo.Username,
            CheckedAt: time.Now(),
            AuditDate: time.Now().Format("2006-01-02 15:04:05")}); err != nil {
            return err
        }
        if err := AddMoveHistory([]*models.Operation{operation}, tx); err != nil {
        if err := service.AddMoveHistory([]*models.Operation{operation}, tx); err != nil {
            return err
        }
        if operation.BaseOperationType == constvar.BaseOperationTypeIncoming {
            locationRoleList, err := models.NewLocationProductSearch().Find()
            if err != nil {
                return errors.New("获取上架规则信息失败")
            if err := service.FinishOperationInput(c, tx, operation, listDetails, mapLocAmount); err != nil {
                return err
            }
            var mapLocationRoleProduct, mapLocationRoleCategory map[string]*models.LocationProduct
            if len(locationRoleList) > 0 {
                mapLocationRoleProduct = make(map[string]*models.LocationProduct)
                mapLocationRoleCategory = make(map[string]*models.LocationProduct)
                for _, v := range locationRoleList {
                    if v.RuleType == constvar.RuleType_Product {
                        mapLocationRoleProduct[strconv.Itoa(v.AreaId)+v.ProductId] = v
                    }
                    if v.RuleType == constvar.RuleType_ProductCategory {
                        mapLocationRoleCategory[strconv.Itoa(v.AreaId)+strconv.Itoa(v.ProductCategoryID)] = v
                    }
                }
            }
            var details []*models.OperationDetails
            for k, v := range listDetails {
                listDetails[k].Product.Amount = listDetails[k].Product.Amount.Add(v.Amount)
                if err := tx.Save(&listDetails[k].Product).Error; err != nil {
                    return err
                }
                if roleProduct, ok := mapLocationRoleProduct[strconv.Itoa(operation.LocationID)+v.ProductId]; ok {
                    detail := &models.OperationDetails{
                        ProductId:      v.ProductId,
                        Amount:         v.Amount,
                        FromLocationID: roleProduct.AreaId,
                        ToLocationID:   roleProduct.LocationId,
                    }
                    details = append(details, detail)
                    if locAmount, aok := mapLocAmount[strconv.Itoa(roleProduct.LocationId)+v.ProductId]; aok {
                        locAmount.Amount = locAmount.Amount.Add(v.Amount)
                        if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
                            return res.Error
                        }
                    } else {
                        if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{
                            LocationId:        roleProduct.LocationId,
                            ProductCategoryID: v.Product.CategoryId,
                            ProductId:         v.ProductId,
                            Amount:            v.Amount,
                            CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
                        }); err != nil {
                            return err
                        }
                    }
                } else {
                    if roleCategory, cok := mapLocationRoleCategory[strconv.Itoa(operation.LocationID)+strconv.Itoa(v.Product.CategoryId)]; cok {
                        detail := &models.OperationDetails{
                            ProductId:      v.ProductId,
                            Amount:         v.Amount,
                            FromLocationID: roleCategory.AreaId,
                            ToLocationID:   roleCategory.LocationId,
                        }
                        details = append(details, detail)
                        if locAmount, aok := mapLocAmount[strconv.Itoa(roleCategory.LocationId)+v.ProductId]; aok {
                            locAmount.Amount = locAmount.Amount.Add(v.Amount)
                            if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
                                return res.Error
                            }
                        } else {
                            if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{
                                LocationId:        roleCategory.LocationId,
                                ProductCategoryID: v.Product.CategoryId,
                                ProductId:         v.ProductId,
                                Amount:            v.Amount,
                                CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
                            }); err != nil {
                                return err
                            }
                        }
                    } else {
                        if locAmount, aok := mapLocAmount[strconv.Itoa(operation.LocationID)+v.ProductId]; aok {
                            locAmount.Amount = locAmount.Amount.Add(v.Amount)
                            if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
                                return res.Error
                            }
                        } else {
                            if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{
                                LocationId:        operation.LocationID,
                                ProductCategoryID: v.Product.CategoryId,
                                ProductId:         v.ProductId,
                                Amount:            v.Amount,
                                CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
                            }); err != nil {
                                return err
                            }
                        }
                    }
                }
            }
            if len(details) > 0 {
                if err := tx.Create(&models.Operation{
                    Number:            operation.Number,
                    SourceNumber:      operation.SourceNumber,
                    OperationTypeId:   0,
                    OperationTypeName: operation.OperationTypeName,
                    Status:            constvar.OperationStatus_Finish,
                    OperationDate:     operation.OperationDate,
                    ContacterID:       operation.ContacterID,
                    ContacterName:     operation.ContacterName,
                    CompanyID:         operation.CompanyID,
                    CompanyName:       operation.CompanyName,
                    Comment:           operation.Comment,
                    BaseOperationType: constvar.BaseOperationTypeInternal,
                    Details:           details,
                    CheckedAt:         time.Now(),
                    CheckedBy:         userInfo.Username,
                }).Error; err != nil {
                    return err
                }
            }
        }
        if operation.BaseOperationType == constvar.BaseOperationTypeOutgoing || operation.BaseOperationType == constvar.BaseOperationTypeDisuse {
            for k, v := range listDetails {
                //todo 演示测试数据
                //data, err := os.ReadFile("conf/input.json")
                //if err != nil {
                //    return errors.New("文件读取失败")
                //}
                //m := make(map[string]interface{})
                //err = json.Unmarshal(data, &m)
                //if err != nil {
                //    return errors.New("格式转换失败")
                //}
                //if opa.OpaCheck(c, m, "operation") {
                //    if v.Product.Amount.LessThan(v.Amount) {
                //        return errors.New(fmt.Sprintf("产品:%v,库存:%v,出库:%v,数量不够,无法完成出库操作", v.Product.Name, v.Product.Amount.String(), v.Amount.String()))
                //    }
                //}
                //todo ================end===============================
                if v.Product.Amount.LessThan(v.Amount) {
                    return errors.New(fmt.Sprintf("产品:%v,库存:%v,出库:%v,数量不够,无法完成出库操作", v.Product.Name, v.Product.Amount.String(), v.Amount.String()))
                }
                listDetails[k].Product.Amount = listDetails[k].Product.Amount.Sub(v.Amount)
                if err := tx.Save(&listDetails[k].Product).Error; err != nil {
                    return err
                }
                if locAmount, aok := mapLocAmount[strconv.Itoa(v.FromLocationID)+v.ProductId]; aok {
                    if locAmount.Amount.LessThan(v.Amount) {
                        return errors.New(fmt.Sprintf("产品:%v,库存:%v,出库:%v,数量不够,无法完成出库操作", v.Product.Name, locAmount.Amount.String(), v.Amount.String()))
                    }
                    locAmount.Amount = locAmount.Amount.Sub(v.Amount)
                    if err := models.NewLocationProductAmountSearch().SetID(locAmount.Id).Update(locAmount); err != nil {
                        return err
                    }
                } else {
                    return errors.New("当前仓库没有该产品,请先入库")
                }
            if err := service.FinishOperationOutput(tx, listDetails, mapLocAmount); err != nil {
                return err
            }
        }
        if operation.BaseOperationType == constvar.BaseOperationTypeInternal {
            for _, v := range listDetails {
                if fromLocAmount, aok := mapLocAmount[strconv.Itoa(v.FromLocationID)+v.ProductId]; aok {
                    if fromLocAmount.Amount.LessThan(v.Amount) {
                        return errors.New(fmt.Sprintf("产品:%v,库存:%v,出库:%v,数量不够,无法完成出库操作", v.Product.Name, fromLocAmount.Amount.String(), v.Amount.String()))
                    }
                    fromLocAmount.Amount = fromLocAmount.Amount.Sub(v.Amount)
                    if err := models.NewLocationProductAmountSearch().SetID(fromLocAmount.Id).Update(fromLocAmount); err != nil {
                        return err
                    }
                } else {
                    return errors.New("当前仓库没有该产品,请先入库")
                }
                if toLocAmount, aok := mapLocAmount[strconv.Itoa(v.ToLocationID)+v.ProductId]; aok {
                    toLocAmount.Amount = toLocAmount.Amount.Add(v.Amount)
                    if err := models.NewLocationProductAmountSearch().SetID(toLocAmount.Id).Update(toLocAmount); err != nil {
                        return err
                    }
                } else {
                    if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{
                        LocationId:        v.ToLocationID,
                        ProductCategoryID: v.Product.CategoryId,
                        ProductId:         v.ProductId,
                        Amount:            v.Amount,
                        CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
                    }); err != nil {
                        return err
                    }
                }
            if err := service.FinishOperationInternal(tx, listDetails, mapLocAmount); err != nil {
                return err
            }
        }
        if operation.BaseOperationType == constvar.BaseOperationTypeAdjust {
            for _, v := range listDetails {
                if locAmount, aok := mapLocAmount[strconv.Itoa(v.ToLocationID)+v.ProductId]; aok {
                    locAmount.Amount = v.Amount
                    if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
                        return res.Error
                    }
                } else {
                    if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{
                        LocationId:        v.ToLocationID,
                        ProductCategoryID: v.Product.CategoryId,
                        ProductId:         v.ProductId,
                        Amount:            v.Amount,
                        CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
                    }); err != nil {
                        return err
                    }
                }
            if err := service.FinishOperationAdjust(tx, listDetails, mapLocAmount); err != nil {
                return err
            }
        }
        return nil
@@ -682,40 +488,6 @@
    }
    util.ResponseFormat(c, code.Success, "操作成功")
}
func AddMoveHistory(operationList []*models.Operation, db *gorm.DB) error {
    var histories []*models.MoveHistory
    operationMap := make(map[int]*models.Operation, len(operationList))
    for _, operation := range operationList {
        for _, v := range operation.Details {
            history := &models.MoveHistory{
                Number:            operation.Number,
                BaseOperationType: operation.BaseOperationType,
                OperationTypeId:   operation.OperationTypeId,
                OperationTypeName: operation.OperationTypeName,
                OperationId:       operation.Id,
                ProductId:         v.ProductId,
                ProductName:       v.Product.Name,
                Amount:            v.Amount,
                Unit:              v.Product.Unit,
                Weight:            operation.Weight,
                FromLocationId:    v.FromLocationID,
                FromLocation:      v.FromLocation.Name,
                ToLocationId:      v.ToLocationID,
                ToLocation:        v.ToLocation.Name,
            }
            histories = append(histories, history)
        }
        operationMap[operation.Id] = operation
    }
    if err := db.Model(&models.MoveHistory{}).Create(&histories).Error; err != nil {
        return err
    }
    for _, history := range histories {
        service.AddNewHistoryReportRecord(history, operationMap[history.OperationId])
    }
    return nil
}
//var (
models/location_product_amount.go
@@ -314,3 +314,13 @@
    }
    return result, nil
}
func (slf *LocationProductAmountSearch) Save(record *LocationProductAmount) error {
    var db = slf.build()
    if err := db.Omit("CreatedAt").Save(record).Error; err != nil {
        return fmt.Errorf("save err: %v, record: %+v", err, record)
    }
    return nil
}
models/operation.go
@@ -51,15 +51,14 @@
        ToLocation         Location `json:"toLocation"      gorm:"foreignKey:ToLocationID;references:Id"` //目标位置
        SalesDetailsNumber string   `gorm:"type:varchar(191);comment:销售明细编码" json:"salesDetailsNumber"`
        ManagerId    string    `json:"managerId" gorm:"type:varchar(255);comment:主管id"`
        Manager      string    `json:"manager" gorm:"type:varchar(255);comment:主管名称"`
        AccountantId string    `json:"accountantId" gorm:"type:varchar(255);comment:会计id"`
        Accountant   string    `json:"accountant" gorm:"type:varchar(255);comment:会计名称"`
        CustodianId  string    `json:"custodianId" gorm:"type:varchar(255);comment:保管员id"`
        Custodian    string    `json:"custodian" gorm:"type:varchar(255);comment:保管员名称"`
        CreatedBy    string    `json:"createBy" gorm:"type:varchar(255);comment:创建者UserId"`
        CheckedBy    string    `json:"checkedBy" gorm:"type:varchar(255);comment:验证者UserId"`
        CheckedAt    time.Time `json:"checkedAt" gorm:"type:datetime;default:null;comment:验证者验证操作时间"`
        ManagerId    string `json:"managerId" gorm:"type:varchar(255);comment:主管id"`
        Manager      string `json:"manager" gorm:"type:varchar(255);comment:主管名称"`
        AccountantId string `json:"accountantId" gorm:"type:varchar(255);comment:会计id"`
        Accountant   string `json:"accountant" gorm:"type:varchar(255);comment:会计名称"`
        CustodianId  string `json:"custodianId" gorm:"type:varchar(255);comment:保管员id"`
        Custodian    string `json:"custodian" gorm:"type:varchar(255);comment:保管员名称"`
        CreatedBy    string `json:"createBy" gorm:"type:varchar(255);comment:创建者UserId"`
        CheckedBy    string `json:"checkedBy" gorm:"type:varchar(255);comment:验证者UserId"`
    }
    OperationSearch struct {
service/move_history.go
New file
@@ -0,0 +1,40 @@
package service
import (
    "gorm.io/gorm"
    "wms/models"
)
func AddMoveHistory(operationList []*models.Operation, db *gorm.DB) error {
    var histories []*models.MoveHistory
    operationMap := make(map[int]*models.Operation, len(operationList))
    for _, operation := range operationList {
        for _, v := range operation.Details {
            history := &models.MoveHistory{
                Number:            operation.Number,
                BaseOperationType: operation.BaseOperationType,
                OperationTypeId:   operation.OperationTypeId,
                OperationTypeName: operation.OperationTypeName,
                OperationId:       operation.Id,
                ProductId:         v.ProductId,
                ProductName:       v.Product.Name,
                Amount:            v.Amount,
                Unit:              v.Product.Unit,
                Weight:            operation.Weight,
                FromLocationId:    v.FromLocationID,
                FromLocation:      v.FromLocation.Name,
                ToLocationId:      v.ToLocationID,
                ToLocation:        v.ToLocation.Name,
            }
            histories = append(histories, history)
        }
        operationMap[operation.Id] = operation
    }
    if err := db.Model(&models.MoveHistory{}).Create(&histories).Error; err != nil {
        return err
    }
    for _, history := range histories {
        AddNewHistoryReportRecord(history, operationMap[history.OperationId])
    }
    return nil
}
service/operation.go
@@ -1,9 +1,15 @@
package service
import (
    "errors"
    "fmt"
    "github.com/gin-gonic/gin"
    "github.com/shopspring/decimal"
    "gorm.io/gorm"
    "strconv"
    "time"
    "wms/constvar"
    "wms/middleware"
    "wms/models"
)
@@ -92,3 +98,213 @@
    return models.NewOperationSearch().CreateBatch(operations)
}
// FinishOperationInput 完成入库
func FinishOperationInput(c *gin.Context, tx *gorm.DB, operation *models.Operation, listDetails []*models.OperationDetails, mapLocAmount map[string]*models.LocationProductAmount) (err error) {
    userInfo := middleware.GetUserInfo(c)
    locationRoleList, err := models.NewLocationProductSearch().Find()
    if err != nil {
        return errors.New("获取上架规则信息失败")
    }
    var mapLocationRoleProduct, mapLocationRoleCategory map[string]*models.LocationProduct
    if len(locationRoleList) > 0 {
        mapLocationRoleProduct = make(map[string]*models.LocationProduct)
        mapLocationRoleCategory = make(map[string]*models.LocationProduct)
        for _, v := range locationRoleList {
            if v.RuleType == constvar.RuleType_Product {
                mapLocationRoleProduct[strconv.Itoa(v.AreaId)+v.ProductId] = v
            }
            if v.RuleType == constvar.RuleType_ProductCategory {
                mapLocationRoleCategory[strconv.Itoa(v.AreaId)+strconv.Itoa(v.ProductCategoryID)] = v
            }
        }
    }
    var details []*models.OperationDetails
    for k, v := range listDetails {
        listDetails[k].Product.Amount = listDetails[k].Product.Amount.Add(v.Amount)
        if err := tx.Save(&listDetails[k].Product).Error; err != nil {
            return err
        }
        if roleProduct, ok := mapLocationRoleProduct[strconv.Itoa(operation.LocationID)+v.ProductId]; ok {
            detail := &models.OperationDetails{
                ProductId:      v.ProductId,
                Amount:         v.Amount,
                FromLocationID: roleProduct.AreaId,
                ToLocationID:   roleProduct.LocationId,
            }
            details = append(details, detail)
            if locAmount, aok := mapLocAmount[strconv.Itoa(roleProduct.LocationId)+v.ProductId]; aok {
                locAmount.Amount = locAmount.Amount.Add(v.Amount)
                if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
                    return res.Error
                }
            } else {
                if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{
                    LocationId:        roleProduct.LocationId,
                    ProductCategoryID: v.Product.CategoryId,
                    ProductId:         v.ProductId,
                    Amount:            v.Amount,
                    CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
                }); err != nil {
                    return err
                }
            }
        } else {
            if roleCategory, cok := mapLocationRoleCategory[strconv.Itoa(operation.LocationID)+strconv.Itoa(v.Product.CategoryId)]; cok {
                detail := &models.OperationDetails{
                    ProductId:      v.ProductId,
                    Amount:         v.Amount,
                    FromLocationID: roleCategory.AreaId,
                    ToLocationID:   roleCategory.LocationId,
                }
                details = append(details, detail)
                if locAmount, aok := mapLocAmount[strconv.Itoa(roleCategory.LocationId)+v.ProductId]; aok {
                    locAmount.Amount = locAmount.Amount.Add(v.Amount)
                    if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
                        return res.Error
                    }
                } else {
                    if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{
                        LocationId:        roleCategory.LocationId,
                        ProductCategoryID: v.Product.CategoryId,
                        ProductId:         v.ProductId,
                        Amount:            v.Amount,
                        CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
                    }); err != nil {
                        return err
                    }
                }
            } else {
                if locAmount, aok := mapLocAmount[strconv.Itoa(operation.LocationID)+v.ProductId]; aok {
                    locAmount.Amount = locAmount.Amount.Add(v.Amount)
                    if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
                        return res.Error
                    }
                } else {
                    if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{
                        LocationId:        operation.LocationID,
                        ProductCategoryID: v.Product.CategoryId,
                        ProductId:         v.ProductId,
                        Amount:            v.Amount,
                        CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
                    }); err != nil {
                        return err
                    }
                }
            }
        }
    }
    if len(details) > 0 {
        if err := tx.Create(&models.Operation{
            Number:            operation.Number,
            SourceNumber:      operation.SourceNumber,
            OperationTypeId:   0,
            OperationTypeName: operation.OperationTypeName,
            Status:            constvar.OperationStatus_Finish,
            OperationDate:     operation.OperationDate,
            ContacterID:       operation.ContacterID,
            ContacterName:     operation.ContacterName,
            CompanyID:         operation.CompanyID,
            CompanyName:       operation.CompanyName,
            Comment:           operation.Comment,
            BaseOperationType: constvar.BaseOperationTypeInternal,
            Details:           details,
            CheckedBy:         userInfo.Username,
        }).Error; err != nil {
            return err
        }
    }
    return nil
}
// FinishOperationOutput 完成出库或报废
func FinishOperationOutput(tx *gorm.DB, listDetails []*models.OperationDetails, mapLocAmount map[string]*models.LocationProductAmount) (err error) {
    for k, v := range listDetails {
        if v.Product.Amount.LessThan(v.Amount) {
            return errors.New(fmt.Sprintf("产品:%v,库存:%v,出库:%v,数量不够,无法完成出库操作", v.Product.Name, v.Product.Amount.String(), v.Amount.String()))
        }
        listDetails[k].Product.Amount = listDetails[k].Product.Amount.Sub(v.Amount)
        if err := models.NewMaterialSearch().SetOrm(tx).Save(&listDetails[k].Product); err != nil {
            return err
        }
        if locAmount, aok := mapLocAmount[strconv.Itoa(v.FromLocationID)+v.ProductId]; aok {
            if locAmount.Amount.LessThan(v.Amount) {
                return errors.New(fmt.Sprintf("产品:%v,库存:%v,出库:%v,数量不够,无法完成出库操作", v.Product.Name, locAmount.Amount.String(), v.Amount.String()))
            }
            locAmount.Amount = locAmount.Amount.Sub(v.Amount)
            if err := models.NewLocationProductAmountSearch().SetID(locAmount.Id).Update(locAmount); err != nil {
                return err
            }
        } else {
            return errors.New("当前仓库没有该产品,请先入库")
        }
    }
    return nil
}
// FinishOperationInternal 完成内部调拨
func FinishOperationInternal(tx *gorm.DB, listDetails []*models.OperationDetails, mapLocAmount map[string]*models.LocationProductAmount) (err error) {
    for _, v := range listDetails {
        if fromLocAmount, aok := mapLocAmount[strconv.Itoa(v.FromLocationID)+v.ProductId]; aok {
            if fromLocAmount.Amount.LessThan(v.Amount) {
                return errors.New(fmt.Sprintf("产品:%v,库存:%v,出库:%v,数量不够,无法完成出库操作", v.Product.Name, fromLocAmount.Amount.String(), v.Amount.String()))
            }
            fromLocAmount.Amount = fromLocAmount.Amount.Sub(v.Amount)
            if err := models.NewLocationProductAmountSearch().SetOrm(tx).SetID(fromLocAmount.Id).Update(fromLocAmount); err != nil {
                return err
            }
        } else {
            return errors.New("当前仓库没有该产品,请先入库")
        }
        if toLocAmount, aok := mapLocAmount[strconv.Itoa(v.ToLocationID)+v.ProductId]; aok {
            toLocAmount.Amount = toLocAmount.Amount.Add(v.Amount)
            if err := models.NewLocationProductAmountSearch().SetOrm(tx).SetID(toLocAmount.Id).Update(toLocAmount); err != nil {
                return err
            }
        } else {
            if err := models.NewLocationProductAmountSearch().SetOrm(tx).Create(&models.LocationProductAmount{
                LocationId:        v.ToLocationID,
                ProductCategoryID: v.Product.CategoryId,
                ProductId:         v.ProductId,
                Amount:            v.Amount,
                CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
            }); err != nil {
                return err
            }
        }
    }
    return nil
}
// FinishOperationAdjust 完成库存调整
func FinishOperationAdjust(tx *gorm.DB, listDetails []*models.OperationDetails, mapLocAmount map[string]*models.LocationProductAmount) (err error) {
    for _, v := range listDetails {
        if locAmount, aok := mapLocAmount[strconv.Itoa(v.ToLocationID)+v.ProductId]; aok {
            locAmount.Amount = v.Amount
            if err := models.NewLocationProductAmountSearch().SetOrm(tx).SetID(locAmount.Id).Save(locAmount); err != nil {
                return err
            }
        } else {
            if err := models.NewLocationProductAmountSearch().SetOrm(tx).Create(&models.LocationProductAmount{
                LocationId:        v.ToLocationID,
                ProductCategoryID: v.Product.CategoryId,
                ProductId:         v.ProductId,
                Amount:            v.Amount,
                CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
            }); err != nil {
                return err
            }
        }
    }
    return nil
}