zhangqian
2024-06-14 72b4fcd52bd82427b3932a5a5c01ced2c0dee201
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("获取上架规则信息失败")
         }
         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 {
         if err := service.FinishOperationInput(c, tx, operation, listDetails, mapLocAmount); 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 {
         if err := service.FinishOperationOutput(tx, listDetails, mapLocAmount); 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 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 {
         if err := service.FinishOperationInternal(tx, listDetails, mapLocAmount); 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 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 {
         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 (