zhangqian
2024-04-07 bd33bea0f3b44e608fcb4d9aa9d1f51a2f5bcf17
api/v1/salesDetails.go
@@ -290,6 +290,7 @@
type GetWarehouseProductInfoReq struct {
   SaleDetailID     int    `json:"saleDetailID,omitempty"`
   SaleDetailNumber string `json:"saleDetailNumber,omitempty"`
   GroupByWarehouse bool   `json:"groupByWarehouse"`
}
// GetDeliveryPrepareInfo
@@ -396,6 +397,133 @@
   ctx.OkWithDetailed(storeList)
}
// GetDeliveryPrepareInfoByWarehouse
// @Tags      SalesDetails
// @Summary   获取产品入库信息按仓库分组
// @Produce   application/json
// @Param      object    body GetWarehouseProductInfoReq   true   "明细编码"
// @Success   200   {object}   response.ListResponse
// @Router      /api/salesDetails/getDeliveryPrepareInfoByWarehouse [post]
func (s *SalesDetailsApi) GetDeliveryPrepareInfoByWarehouse(c *gin.Context) {
   var params GetWarehouseProductInfoReq
   ctx, ok := contextx.NewContext(c, &params)
   if !ok {
      return
   }
   if params.SaleDetailID == 0 {
      ctx.FailWithMsg(ecode.ParamsErr, "参数缺失")
      return
   }
   salesDetails, err := salesDetailsService.GetSalesDetails(params.SaleDetailID)
   if err == gorm.ErrRecordNotFound || salesDetails.Number != params.SaleDetailNumber {
      ctx.FailWithMsg(ecode.ParamsErr, "销售订单不存在")
      return
   }
   productMap := model.ProductMap(salesDetails.Products)
   client := product_inventory.NewProductInventoryServiceClient(grpc_init.ProductInventoryServiceConn)
   grpcResp, err := client.GetOrderInputAndOutputInfo(ctx.GetCtx(), &product_inventory.GetOrderInputAndOutputInfoRequest{
      Number: params.SaleDetailNumber,
   })
   if err != nil {
      if strings.Contains(err.Error(), "record not found") {
         ctx.Ok()
         return
      }
      logx.Errorf("GetOrderInputAndOutputInfo err: %v", err.Error())
      ctx.FailWithMsg(ecode.UnknownErr, "grpc调用错误")
      return
   }
   grpcOutputList := grpcResp.OutputList
   grpcInputList := grpcResp.InputList
   inputProductMap := make(map[int64]map[string]*response.StoreInfo)
   outputProductMap := make(map[int64]map[string]*response.OutputSimpleInfo)
   warehouseIds := make([]int64, 0)
   warehouseIdMap := make(map[int64]string, 0)
   for _, v := range grpcOutputList {
      if productMap[v.Number] == nil {
         continue
      }
      if outputProductMap[v.WareHouseID] == nil {
         outputProductMap[v.WareHouseID] = make(map[string]*response.OutputSimpleInfo)
      }
      if outputProductMap[v.WareHouseID][v.Number] == nil {
         simpleInfo := &response.OutputSimpleInfo{
            Number: v.Number,
         }
         amount, _ := decimal.NewFromString(v.Amount)
         simpleInfo.Amount = amount
         outputProductMap[v.WareHouseID][v.Number] = simpleInfo
      } else {
         amount, _ := decimal.NewFromString(v.Amount)
         outputProductMap[v.WareHouseID][v.Number].Amount = outputProductMap[v.WareHouseID][v.Number].Amount.Add(amount)
      }
   }
   for _, v := range grpcInputList {
      if _, ok := warehouseIdMap[v.WareHouseID]; !ok {
         warehouseIds = append(warehouseIds, v.WareHouseID)
         warehouseIdMap[v.WareHouseID] = v.Warehouse
      }
      if productMap[v.Number] == nil {
         continue
      }
      if inputProductMap[v.WareHouseID] == nil {
         inputProductMap[v.WareHouseID] = make(map[string]*response.StoreInfo)
      }
      if inputProductMap[v.WareHouseID][v.Number] == nil {
         storeInfo := &response.StoreInfo{
            Number:      v.Number,
            Name:        v.Name,
            OrderAmount: productMap[v.Number].Amount,
         }
         finishAmount, _ := decimal.NewFromString(v.Amount)
         storeInfo.FinishAmount = finishAmount
         storeInfo.AvailableAmount = finishAmount
         storeInfo.LeftAmount = storeInfo.OrderAmount
         inputProductMap[v.WareHouseID][v.Number] = storeInfo
      } else {
         finishAmount, _ := decimal.NewFromString(v.Amount)
         inputProductMap[v.WareHouseID][v.Number].FinishAmount = inputProductMap[v.WareHouseID][v.Number].FinishAmount.Add(finishAmount)
         inputProductMap[v.WareHouseID][v.Number].AvailableAmount = inputProductMap[v.WareHouseID][v.Number].FinishAmount
      }
   }
   data := make([]*response.StoreInfoWithWarehouse, 0)
   for _, houseId := range warehouseIds {
      storeList := make([]*response.StoreInfo, 0, len(salesDetails.Products))
      for _, product := range salesDetails.Products {
         storeInfo := inputProductMap[houseId][product.Number]
         if storeInfo == nil { //没有入库信息
            storeInfo = &response.StoreInfo{
               Name:            product.Name,
               Number:          product.Number,
               OrderAmount:     product.Amount,
               FinishAmount:    decimal.Decimal{},
               LeftAmount:      product.Amount,
               AvailableAmount: decimal.Decimal{},
            }
         } else { //有入库数量再查出库,算出未发货数量
            if outputProductMap[houseId][product.Number] != nil {
               outputInfo := outputProductMap[houseId][product.Number]
               storeInfo.LeftAmount = storeInfo.LeftAmount.Sub(outputInfo.Amount)           //剩余发货数量 = 订单数量 - 已发货数量
               storeInfo.AvailableAmount = storeInfo.AvailableAmount.Sub(outputInfo.Amount) //可用数量 = 入库完成数量 - 已发货数量
            }
         }
         storeList = append(storeList, storeInfo)
      }
      data = append(data, &response.StoreInfoWithWarehouse{
         WarehouseId:   houseId,
         WarehouseName: warehouseIdMap[houseId],
         StoreInfoList: storeList,
      })
   }
   ctx.OkWithDetailed(data)
}
// ConfirmOutput
// @Tags      SalesDetails
// @Summary   确认发货