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
|
}
|
}
|