yinbentan
2024-07-06 79aef24a785581d95343ccd99e9cb362b2bc9c97
controllers/operation.go
@@ -9,8 +9,6 @@
   "github.com/shopspring/decimal"
   "github.com/xuri/excelize/v2"
   "gorm.io/gorm"
   "io/ioutil"
   "sort"
   "strconv"
   "strings"
   "time"
@@ -95,7 +93,15 @@
      params.WarehouseId = operationType.WarehouseId
   }
   if params.DealerType == "" {
      CheckInventoryDealerType(&params)
   }
   userInfo := middleware.GetUserInfo(c)
   if userInfo == nil {
      util.ResponseFormat(c, code.SetStatusError, "登录用户信息为空,请登录后重试!")
      return
   }
   params.CreatedBy = userInfo.Username
   params.Status = constvar.OperationStatus_Ready
   //params.Number = strconv.FormatInt(time.Now().Unix(), 10)
@@ -140,19 +146,52 @@
   util.ResponseFormat(c, code.Success, "添加成功")
}
func CheckDetailsRepeat(details []*models.OperationDetails) bool {
   var detailIDs []string
   var tempID string
   for _, v := range details {
      detailIDs = append(detailIDs, v.ProductId)
func CheckInventoryDealerType(params *models.Operation) {
   var dictType constvar.MiniDictType
   dictName := "其他"
   switch params.BaseOperationType {
   case constvar.BaseOperationTypeIncoming:
      dictType = constvar.StorageType
      //dictName = dictName + "入库"
   case constvar.BaseOperationTypeOutgoing:
      dictType = constvar.StockoutType
      //dictName = dictName + "出库"
   case constvar.BaseOperationTypeInternal:
      dictType = constvar.TransferType
      //dictName = dictName + "调拨"
   case constvar.BaseOperationTypeDisuse:
      dictType = constvar.DisuseType
      //dictName = dictName + "报废"
   case constvar.BaseOperationTypeAdjust:
      dictType = constvar.TakeStockType
      //dictName = dictName + "盘点"
   default:
      return
   }
   sort.Strings(detailIDs)
   for _, v := range detailIDs {
      if v != tempID {
         tempID = v
      } else {
         return true
   miniDict, err := models.NewMiniDictSearch().SetType(dictType).SetName(dictName).First()
   if err == gorm.ErrRecordNotFound {
      miniDict = &models.MiniDict{
         Type: dictType,
         Name: dictName,
      }
      models.NewMiniDictSearch().Create(miniDict)
   }
   params.DealerType = miniDict.Name
}
// CheckDetailsRepeat 出库、入库、盘点涉及产品重复性检查(以产品编号、出库库房编号、入库库房编号)
// 存在重复值 true; 不存在返回 false
func CheckDetailsRepeat(details []*models.OperationDetails) bool {
   if len(details) == 0 {
      return false
   }
   var detailKeyMap = make(map[string]bool)
   for _, v := range details {
      key := fmt.Sprintf("%v%v%v", v.ProductId, v.FromLocationID, v.ToLocationID)
      detailKeyMap[key] = true
   }
   if len(detailKeyMap) != len(details) { // 长度相同,不存在重复值;长度不同存在存在不同
      return true
   }
   return false
}
@@ -213,12 +252,8 @@
   if params.OperationTypeId == 0 && int(params.BaseOperationType) == 0 {
      return errors.New("未识别该记录类型1")
   }
   if params.BaseOperationType != 0 {
      if params.WarehouseId == 0 {
         return errors.New("未识别该记录类型2")
      }
   } else if params.OperationTypeId == 0 && params.BaseOperationType != 0 && params.WarehouseId == 0 {
      return errors.New("未识别该记录类型2")
   }
   if params.OperationDate == "" {
@@ -251,12 +286,11 @@
// GetOperationInfo
// @Tags      入库/出库
// @Summary   入库/出库列表
// @Summary   操作详情接口
// @Produce   application/json
//
//   @Param      id   path      string         true   "id"
//
// @Success   200 {object} util.Response   "成功"
// @Param     id path  string true "id"
// @Param     Authorization   header string true "token"
// @Success   200 {object} util.Response{data=models.Operation}   "成功"
// @Router    /api-wms/v1/operation/getOperationInfo/{id} [get]
func (slf OperationController) GetOperationInfo(c *gin.Context) {
   number := c.Param("id")
@@ -270,6 +304,26 @@
      util.ResponseFormat(c, code.RequestParamError, err.Error())
      return
   }
   if operation.BaseOperationType == constvar.BaseOperationTypeOutgoing || operation.BaseOperationType == constvar.BaseOperationTypeInternal { //查询实时在库库存
      productIds := make([]string, 0)
      locationIds := make([]int, 0)
      for _, v := range operation.Details {
         productIds = append(productIds, v.ProductId)
         locationIds = append(locationIds, v.FromLocationID)
      }
      locationAmountMap, err := service.GetLocationAmounts(productIds, locationIds)
      if err != nil {
         util.ResponseFormat(c, code.RequestParamError, "查询产品库存错误")
         return
      }
      for _, v := range operation.Details {
         if locationAmountMap[v.ProductId] != nil {
            v.StockAmount = locationAmountMap[v.ProductId][v.FromLocationID]
         }
      }
   }
   util.ResponseFormat(c, code.Success, operation)
}
@@ -278,7 +332,7 @@
// @Summary   入库/出库列表
// @Produce   application/json
// @Param       object  body  request.OperationList true  "查询参数"
// @Success   200 {object} util.ResponseList{data=[]models.Operation}   "成功"
// @Success   200   {object}   util.ResponseList{data=[]models.Operation}   "成功"
// @Router    /api-wms/v1/operation/list [post]
func (slf OperationController) List(c *gin.Context) {
   var params request.OperationList
@@ -316,7 +370,26 @@
      util.ResponseFormat(c, code.RequestError, "查找失败:"+err.Error())
      return
   }
   //userList, err := user.GetUserList()
   //userMap := make(map[string]string)
   //if err == nil {
   //   for _, user := range userList {
   //      userMap[user.UserName] = user.NickName
   //   }
   //}
   userInfo := middleware.GetUserInfo(c)
   if userInfo == nil {
      util.ResponseFormat(c, code.SetStatusError, "登录用户信息为空,请登录后重试!")
      return
   }
   for _, v := range list {
      v.CreatedBy = userInfo.NickName
      //if err == nil {
      if userInfo != nil {
         //   v.CreatedBy = userMap[v.CreatedBy]
         //   v.CheckedBy = userMap[v.CheckedBy]
         v.CheckedBy = userInfo.NickName
      }
      for _, v1 := range v.Details {
         //v1.SalePrice = decimal.NewFromFloat(1.2345)
         //v1.Cost = decimal.NewFromFloat(9.678)
@@ -791,16 +864,13 @@
               util.ResponseFormat(c, code.RequestParamError, err.Error())
               return
            }
         } else if warehouse.FileTemplateCategoryIn == constvar.FileTemplateCategory_JialianInput1 {
            fileUrl, err = JialianOperation2(warehouse.FileTemplateCategoryIn, operation)
         } else {
            fileUrl, err = JialianOperation2(constvar.FileTemplateCategory_JialianInput1, operation)
            if err != nil {
               util.ResponseFormat(c, code.RequestParamError, err.Error())
               return
            }
         }
      } else if companyName == "geruimi" {
         fileUrl, err = ExportInputSelfmade(constvar.FileTemplateCategory_Selfmade, operation)
         if err != nil {
@@ -832,8 +902,8 @@
               return
            }
         } else if warehouse.FileTemplateCategoryOut == constvar.FileTemplateCategory_JialianOutput1 {
            fileUrl, err = JialianOperation2(warehouse.FileTemplateCategoryOut, operation)
         } else {
            fileUrl, err = JialianOperation2(constvar.FileTemplateCategory_JialianOutput1, operation)
            if err != nil {
               util.ResponseFormat(c, code.RequestParamError, err.Error())
               return
@@ -873,8 +943,6 @@
   // 读取模板内容
   f, err := excelize.OpenReader(readerCloser)
   //fl, err := os.Open("E:\\家纺出入库单.xlsx")
   //f, err := excelize.OpenReader(fl)
   if err != nil {
      return "", errors.New("读取excel模版失败:" + err.Error())
   }
@@ -926,11 +994,13 @@
   totalAmount := decimal.NewFromInt(0) // 总金额
   totalPrice := decimal.NewFromInt(0)  // 总价
   rowIndex := 6
   str := ""
   for i, v := range operation.Details {
      //设置表单最多6条数据
      if i > 6 {
         break
      }
      str += v.Remark
      f.SetCellValue(sheet, "B"+strconv.Itoa(rowIndex), v.Product.Name)                                                          // 产品名称
      f.SetCellValue(sheet, "C"+strconv.Itoa(rowIndex), v.Product.Specs)                                                         //规格
      f.SetCellValue(sheet, "D"+strconv.Itoa(rowIndex), attributeValueMap[fmt.Sprintf("%d%s", attributeMap["颜色"], v.ProductId)]) //颜色
@@ -990,7 +1060,8 @@
   }
   // 备注 第13行
   f.SetCellValue(sheet, "B13", "备注:"+operation.Remark)
   //f.SetCellValue(sheet, "B13", "备注:"+operation.Comment)
   f.SetCellValue(sheet, "B13", "备注:"+str)
   // 第14行
   f.SetCellValue(sheet, "C14", operation.Manager)    // 审核
   f.SetCellValue(sheet, "F14", operation.Accountant) // 保管
@@ -1002,7 +1073,6 @@
   fileUrl, err := upload.UploadFileToSeaWeed(string(constvar.FileType_File), uuid.NewV4().String()+".xlsx", buf.Bytes())
   if err != nil {
      ioutil.WriteFile("E:\\"+uuid.NewV4().String()+".xlsx", buf.Bytes(), 0644)
      logx.Errorf("file upload err: %v", err)
      return "", err
   }
@@ -1039,11 +1109,13 @@
   totalAmount := decimal.NewFromInt(0) // 总金额
   totalPrice := decimal.NewFromInt(0)  // 总价
   rowIndex := 5
   str := ""
   for i, v := range operation.Details {
      //设置表单最多9条数据
      if i > 9 {
         break
      }
      str += v.Remark
      f.SetCellValue(sheet, "A"+strconv.Itoa(rowIndex), v.Product.Name)    // 品名
      f.SetCellValue(sheet, "B"+strconv.Itoa(rowIndex), v.Product.Type)    // 型号
      f.SetCellValue(sheet, "C"+strconv.Itoa(rowIndex), v.Product.Unit)    // 单位
@@ -1107,7 +1179,8 @@
      }
   }
   f.SetCellValue(sheet, "Q5", operation.Remark) // 备注
   //f.SetCellValue(sheet, "Q5", operation.Comment) // 备注
   f.SetCellValue(sheet, "Q5", str) // 备注
   // 第14行
   f.SetCellValue(sheet, "B15", operation.Manager)    // 主管
@@ -1121,7 +1194,6 @@
   fileUrl, err := upload.UploadFileToSeaWeed(string(constvar.FileType_File), uuid.NewV4().String()+".xlsx", buf.Bytes())
   if err != nil {
      ioutil.WriteFile("E:\\"+uuid.NewV4().String()+".xlsx", buf.Bytes(), 0644)
      logx.Errorf("file upload err: %v", err)
      return "", err
   }
@@ -1378,8 +1450,7 @@
// @Tags      入库/出库
// @Summary   获取人员列表
// @Produce   application/json
// @Param     object  body  request.OperationCondition true  "参数"
// @Success   200 {object} util.ResponseList{data=[]inventory_order.WorkerInfo} "成功"
// @Success   200 {object} util.Response "成功"
// @Router    /api-wms/v1/operation/getPersonnelList [get]
func (slf OperationController) GetPersonnelList(c *gin.Context) {
   cli := inventory_order.NewInventoryOrderServiceClient(init_client.ApsConn)