package controllers import ( "github.com/gin-gonic/gin" "github.com/shopspring/decimal" "gorm.io/gorm" "strconv" "strings" "time" "wms/constvar" "wms/extend/code" "wms/extend/util" "wms/models" "wms/pkg/timex" "wms/proto/init_client" "wms/proto/inventory_order" "wms/proto/purchase_wms" "wms/request" ) type ReorderRuleController struct { } // AddReorderRule // @Tags 重订货规则 // @Summary 添加重订货规则 // @Produce application/json // @Param object body models.ReorderRule true "重订货规则" // @Success 200 {object} util.Response "成功" // @Router /api-wms/v1/reorderRule/addReorderRule [post] func (slf ReorderRuleController) AddReorderRule(c *gin.Context) { var params models.ReorderRule if err := c.BindJSON(¶ms); err != nil { util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误") return } count, err := models.NewReorderRuleSearch().SetProductId(params.ProductId).SetLocationId(params.LocationId).Count() if err != nil { util.ResponseFormat(c, code.RequestError, "数据验证错误") return } if count > 0 { util.ResponseFormat(c, code.RequestError, "当前位置已存在相同产品的重订货规则") return } err = models.NewReorderRuleSearch().Create(¶ms) if err != nil { util.ResponseFormat(c, code.RequestError, "重订货规则保存失败") return } util.ResponseFormat(c, code.Success, "保存成功") } // GetReorderRuleList // @Tags 重订货规则 // @Summary 获取重订货规则列表 // @Produce application/json // @Param object body request.GetReorderRuleList true "参数" // @Success 200 {object} util.ResponseList{data=[]models.ReorderRule} "成功" // @Router /api-wms/v1/reorderRule/getReorderRuleList [post] func (slf ReorderRuleController) GetReorderRuleList(c *gin.Context) { var params request.GetReorderRuleList if err := c.BindJSON(¶ms); err != nil { util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误") return } search := models.NewReorderRuleSearch() if params.PageInfo.Check() { search.SetPage(params.Page, params.PageSize) } rules, total, err := search.SetPreload(true).SetKeyword(params.KeyWord).SetLocationId(params.LocationId).SetProductId(params.ProductId).Find() if err != nil { util.ResponseFormat(c, code.RequestParamError, "查询重订货规则列表失败") return } productIds := make([]string, 0) locationIds := make([]int, 0) for _, rule := range rules { productIds = append(productIds, rule.ProductId) locationIds = append(locationIds, rule.LocationId) } if params.LocationId != 0 { locationIds = []int{params.LocationId} } if params.ProductId != "" { productIds = []string{params.ProductId} } //在库 amounts, err := models.NewLocationProductAmountSearch().SetProductIds(productIds).SetLocationIds(locationIds).Find() if err != nil { util.ResponseFormat(c, code.RequestParamError, "查询在库数量失败") return } for _, rule := range rules { for _, amount := range amounts { if rule.ProductId == amount.ProductId && rule.LocationId == amount.LocationId { rule.Amount = rule.Amount.Add(amount.Amount) } } } //预测 //入库就绪 var status = []constvar.OperationStatus{constvar.OperationStatus_Ready} var operationType = []constvar.BaseOperationType{constvar.BaseOperationTypeIncoming, constvar.BaseOperationTypeInternal} amount, err := GetProductAmount(productIds, locationIds, nil, status, operationType) if err != nil { util.ResponseFormat(c, code.RequestParamError, "查询重订货规则列表失败") return } for _, rule := range rules { for _, productAmount := range amount { if rule.ProductId == productAmount.ProductId && rule.LocationId == productAmount.ToLocationId { rule.Prediction = rule.Prediction.Add(productAmount.Amount) } } rule.Prediction = rule.Amount.Add(rule.Prediction) } //出库就绪 operationType = []constvar.BaseOperationType{constvar.BaseOperationTypeOutgoing, constvar.BaseOperationTypeInternal, constvar.BaseOperationTypeDisuse} amount, err = GetProductAmount(productIds, nil, locationIds, status, operationType) if err != nil { util.ResponseFormat(c, code.RequestParamError, "查询重订货规则列表失败") return } for _, rule := range rules { for _, productAmount := range amount { if rule.ProductId == productAmount.ProductId && rule.LocationId == productAmount.FromLocationId { rule.Prediction = rule.Prediction.Sub(productAmount.Amount) } } } var result []*models.ReorderRule if params.Type == "" { result = rules } else { for _, rule := range rules { if rule.MinInventory.GreaterThan(rule.Prediction) { result = append(result, rule) } } } util.ResponseFormatList(c, code.Success, result, int(total)) } // 计算在库与预测数量 func GetProductAmount(productIds []string, toLocationIds []int, fromLocationIds []int, status []constvar.OperationStatus, operationType []constvar.BaseOperationType) ([]request.ProductAmount, error) { var pa []request.ProductAmount search := models.NewOperationDetailsSearch() search.Orm = search.Orm.Model(&models.OperationDetails{}). Select("wms_operation_details.product_id, wms_operation_details.amount, wms_operation_details.to_location_id as to_location_id, " + "wms_operation_details.from_location_id as from_location_id, wms_operation.base_operation_type"). Joins("left join wms_operation on wms_operation_details.operation_id = wms_operation.id") if len(productIds) > 0 { search.Orm.Where("wms_operation_details.product_id in (?)", productIds) } if len(toLocationIds) > 0 { search.Orm.Where("wms_operation_details.to_location_id in (?)", toLocationIds) } if len(fromLocationIds) > 0 { search.Orm.Where("wms_operation_details.from_location_id in (?)", fromLocationIds) } if len(status) > 0 { search.Orm.Where("wms_operation.status in (?)", status) } if len(operationType) > 0 { search.Orm.Where("wms_operation.base_operation_type in (?)", operationType) } err := search.Orm.Find(&pa).Error return pa, err } // GetAmountAndPrediction // @Tags 重订货规则 // @Summary 获取在库与预测数量 // @Produce application/json // @Param object body request.GetAmountAndPrediction true "重订货规则" // @Success 200 {object} util.ResponseList{data=[]map[string]interface{}} "成功" // @Router /api-wms/v1/reorderRule/getAmountAndPrediction [post] func (slf ReorderRuleController) GetAmountAndPrediction(c *gin.Context) { var params request.GetAmountAndPrediction if err := c.BindJSON(¶ms); err != nil { util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误") return } productIds := make([]string, 0) locationIds := make([]int, 0) productIds = append(productIds, params.ProductId) locationIds = append(locationIds, params.LocationId) amount := decimal.NewFromInt(0) prediction := decimal.NewFromInt(0) //在库 find, err := models.NewLocationProductAmountSearch().SetProductIds(productIds).SetLocationIds(locationIds).Find() if err != nil { util.ResponseFormat(c, code.RequestParamError, "查询在库数量失败") return } for _, productAmount := range find { if params.ProductId == productAmount.ProductId && params.LocationId == productAmount.LocationId { amount = amount.Add(productAmount.Amount) } } //预测 //入库就绪 var status = []constvar.OperationStatus{constvar.OperationStatus_Ready} var operationType = []constvar.BaseOperationType{constvar.BaseOperationTypeIncoming, constvar.BaseOperationTypeInternal} list, err := GetProductAmount(productIds, locationIds, nil, status, operationType) if err != nil { util.ResponseFormat(c, code.RequestParamError, "查询重订货规则列表失败") return } for _, productAmount := range list { if params.ProductId == productAmount.ProductId && params.LocationId == productAmount.ToLocationId { prediction = prediction.Add(productAmount.Amount) } } prediction = amount.Add(prediction) //出库就绪 operationType = []constvar.BaseOperationType{constvar.BaseOperationTypeOutgoing, constvar.BaseOperationTypeInternal, constvar.BaseOperationTypeDisuse} list, err = GetProductAmount(productIds, nil, locationIds, status, operationType) if err != nil { util.ResponseFormat(c, code.RequestParamError, "查询重订货规则列表失败") return } for _, productAmount := range list { if params.ProductId == productAmount.ProductId && params.LocationId == productAmount.FromLocationId { prediction = prediction.Sub(productAmount.Amount) } } m := make(map[string]int64) m["amount"] = amount.IntPart() m["prediction"] = prediction.IntPart() util.ResponseFormat(c, code.Success, m) } // UpdateReorderRule // @Tags 重订货规则 // @Summary 更新重订货规则 // @Produce application/json // @Param object body models.ReorderRule true "重订货规则" // @Success 200 {object} util.Response "成功" // @Router /api-wms/v1/reorderRule/updateReorderRule [post] func (slf ReorderRuleController) UpdateReorderRule(c *gin.Context) { var params models.ReorderRule if err := c.BindJSON(¶ms); err != nil { util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误") return } err := models.NewReorderRuleSearch().SetID(params.Id).Update(¶ms) if err != nil { util.ResponseFormat(c, code.RequestError, "重订货规则更新失败") return } util.ResponseFormat(c, code.Success, "更新成功") } //var InventoryOrderServiceConn *grpc.ClientConn // //func InitInventoryOrderServiceConn() { // var err error // InventoryOrderServiceConn, err = grpc.Dial(conf.GrpcServerConf.ApsAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) // if err != nil { // logx.Errorf("grpc dial product service error: %v", err.Error()) // return // } //} // //func CloseInventoryOrderServiceConn() { // if InventoryOrderServiceConn != nil { // InventoryOrderServiceConn.Close() // } //} // OrderAgain // @Tags 重订货规则 // @Summary 再订一次 // @Produce application/json // @Param object body models.ReorderRule true "重订货规则" // @Success 200 {object} util.Response "成功" // @Router /api-wms/v1/reorderRule/orderAgain [post] func (slf ReorderRuleController) OrderAgain(c *gin.Context) { var params models.ReorderRule if err := c.BindJSON(¶ms); err != nil { util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误") return } if params.Route == "采购" { client := purchase_wms.NewPurchaseServiceClient(init_client.SrmConn) resp, err := client.GetSupplierListByProductId(c, &purchase_wms.GetSupplierListByProductIdRequest{ProductId: params.ProductId}) if err != nil { util.ResponseFormat(c, code.RequestParamError, "grpc调用失败") return } util.ResponseFormat(c, code.Success, resp.List) return } client := inventory_order.NewInventoryOrderServiceClient(init_client.ApsConn) order, err := client.CreateNewOrder(c, &inventory_order.CreateNewOrderRequest{ OrderNumber: params.OrderNumber.IntPart(), Unit: params.Unit, ProductId: params.ProductId, Customer: "WMS推送", }) if err != nil { util.ResponseFormat(c, code.RequestParamError, "grpc调用失败") return } err = orderAgain(params, order.OrderId) if err != nil { util.ResponseFormat(c, code.RequestParamError, "重订失败") return } util.ResponseFormat(c, code.Success, "重订成功") } func orderAgain(params models.ReorderRule, SourceNumber string) error { location, err := models.NewLocationSearch().SetID(params.LocationId).First() if err != nil { return err } houseCode := strings.Split(location.JointName, "/")[0] var operationType models.OperationType err = models.NewOperationTypeSearch().Orm.Model(&models.OperationType{}).Joins("left join wms_warehouse on wms_job_type.warehouse_id = wms_warehouse.id"). Where("wms_job_type.base_operation_type = 1 and wms_warehouse.code = ?", houseCode).First(&operationType).Error if err != nil { return err } var operation models.Operation var details models.OperationDetails details.ProductId = params.ProductId details.Amount = params.OrderNumber details.FromLocationID = 1 details.ToLocationID = params.LocationId operation.Details = append(operation.Details, &details) operation.BaseOperationType = constvar.BaseOperationTypeIncoming operation.Status = constvar.OperationStatus_Ready operation.OperationTypeId = operationType.Id operation.OperationTypeName = operationType.Name operation.OperationDate = timex.TimeToString2(time.Now()) operation.LocationID = params.LocationId operation.Number = strconv.FormatInt(time.Now().Unix(), 10) operation.SourceNumber = SourceNumber err = models.WithTransaction(func(db *gorm.DB) error { if err = models.NewOperationSearch().SetOrm(db).Create(&operation); err != nil { return err } params.OrderNumber = decimal.NewFromInt(0) err = models.NewReorderRuleSearch().SetOrm(db).SetID(params.Id).Update(¶ms) return err }) return err } // SubmitOrder // @Tags 重订货规则 // @Summary 再订一次 // @Produce application/json // @Param object body models.ReorderRule true "参数" // @Success 200 {object} util.Response "成功" // @Router /api-wms/v1/reorderRule/submitOrder [post] func (slf ReorderRuleController) SubmitOrder(c *gin.Context) { var params models.ReorderRule client := purchase_wms.NewPurchaseServiceClient(init_client.SrmConn) resp, err := client.CreatePurchaseByWms(c, &purchase_wms.CreatePurchaseByWmsRequest{ SupplierId: params.SupplierId, ProductId: params.ProductId, Amount: params.OrderNumber.IntPart(), Source: "APS", }) if err != nil { util.ResponseFormat(c, code.RequestParamError, "grpc调用失败") return } err = orderAgain(params, resp.PurchaseNumber) if err != nil { util.ResponseFormat(c, code.RequestParamError, "重订失败") return } }