订单拆分测试

This commit is contained in:
苏尹岚
2020-03-16 09:15:39 +08:00
parent 678d2f4d0a
commit 2a43dc0238
2 changed files with 206 additions and 129 deletions

View File

@@ -105,6 +105,7 @@ type GoodsOrder struct {
VendorOrgCode string `orm:"size(64)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空
FromStoreID int `orm:"column(from_store_id)" json:"fromStoreID"` //物料配送门店
EclpOutID string `orm:"column(eclp_out_id)" json:"eclpOutID"` //物料配送的出库单号
AddressID int64 `orm:"column(address_id)" json:"addressID"` //配送地址ID
// 以下只是用于传递数据
OriginalData string `orm:"-" json:"-"`

View File

@@ -60,6 +60,18 @@ type JxSkuInfo struct {
GroupSign bool `json:"groupSign"`
}
type JxSkuInfo2 struct {
SkuID int `json:"skuID"`
Count int `json:"count"`
Price int64 `json:"price,omitempty"` // 原价
SalePrice int64 `json:"salePrice,omitempty"` // 售卖价
Name string `json:"name"`
Weight int `json:"weight"`
GroupSign bool `json:"groupSign"`
}
type JxSkuInfoList []*JxSkuInfo
func (l JxSkuInfoList) Len() int {
@@ -193,6 +205,7 @@ func CreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64,
outJxOrder.OrderID = GenOrderNo(ctx)
order, err2 := jxOrder2GoodsOrder(ctx, outJxOrder, deliveryAddress)
if err = err2; err == nil {
order.AddressID = addressID
order.Status = model.OrderStatusWait4Pay
callNewOrder(order)
}
@@ -611,19 +624,19 @@ func generateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64
}
deliveryAddress.ConsigneeName = storeDetail2.Name
outJxOrder.FromStoreID = fromStoreID
// if outJxOrder.Weight > 5000 {
// _, freightPrice, err := tryToSplitMatterOrder(outJxOrder)
// if err != nil {
// return nil, nil, err
// }
// outJxOrder.FreightPrice = int64(freightPrice)
// } else {
if outJxOrder.Weight <= 2000 {
outJxOrder.FreightPrice = 500
if outJxOrder.Weight > 5000 {
_, freightPrice, err := tryToSplitMatterOrder(outJxOrder)
if err != nil {
return nil, nil, err
}
outJxOrder.FreightPrice = int64(freightPrice)
} else {
outJxOrder.FreightPrice = utils.Float64TwoInt64(500 + math.Ceil((utils.Int2Float64(outJxOrder.Weight)-2000)/1000)*200)
if outJxOrder.Weight <= 2000 {
outJxOrder.FreightPrice = 500
} else {
outJxOrder.FreightPrice = utils.Float64TwoInt64(500 + math.Ceil((utils.Int2Float64(outJxOrder.Weight)-2000)/1000)*200)
}
}
// }
} else {
if outJxOrder.FreightPrice > specialFreightPrice {
outJxOrder.FreightPrice = specialFreightPrice
@@ -645,71 +658,6 @@ func generateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64
return outJxOrder, deliveryAddress, err
}
func tryToSplitMatterOrder(jxOrder *JxOrderInfo) (outOrders []*JxOrderInfo, freightPrice int, err error) {
var (
skus = jxOrder.Skus
weightList []*JxSkuInfo
weightMap = make(map[int]*JxSkuInfo)
flag = true
)
for _, v := range skus {
for i := 0; i < v.Count; i++ {
weightList = append(weightList, v)
}
}
for i := 0; i < len(weightList)-1; i++ {
for j := 0; j < len(weightList)-i-1; j++ {
if weightList[j].Weight < weightList[j+1].Weight {
tmp := weightList[j]
weightList[j] = weightList[j+1]
weightList[j+1] = tmp
}
}
}
for k, v := range weightList {
weightMap[k+1] = v
}
outOrders = loop(weightMap, flag, jxOrder)
return outOrders, freightPrice, err
}
func loop(weightMap map[int]*JxSkuInfo, flag bool, jxOrder *JxOrderInfo) (outOrders []*JxOrderInfo) {
sum5 := 0
sum3 := 0
for i := 1; i <= len(weightMap); i++ {
outOrder := &JxOrderInfo{}
outOrder = jxOrder
for j := 1; j <= len(weightMap); {
if flag {
if !weightMap[j].GroupSign {
sum5 += weightMap[j].Weight
if weightMap[j].Weight+sum5 <= 5 {
outOrder.Skus = append(outOrder.Skus, weightMap[j])
weightMap[j].GroupSign = true
} else {
j++
continue
}
}
} else {
if !weightMap[j].GroupSign {
sum3 += weightMap[j].Weight
if weightMap[j].Weight+sum3 <= 3 {
outOrder.Skus = append(outOrder.Skus, weightMap[j])
weightMap[j].GroupSign = true
} else {
j++
continue
}
}
}
}
flag = false
outOrders = append(outOrders, outOrder)
}
return outOrders
}
func matterSkusLimited(skus []*JxSkuInfo, storeID int) (err error) {
result, err := orderman.GetMatterStoreOrderCount(nil, storeID)
sum := 0
@@ -827,60 +775,89 @@ func orderSolutionForWuLiao(order *model.GoodsOrder) (err error) {
return err
}
orderSkus := goods[0].Skus
// if order.Weight <= 5000 { //如果总重量小于5kg就直接发单
var (
goodsNos []string
prices []string
quantities []string
)
err = changeOrderStatus(order.VendorOrderID, model.OrderStatusDelivering, "")
for _, v := range orderSkus {
skus, err := dao.GetSkus(db, []int{v.SkuID}, nil, nil, nil, nil)
if err != nil || len(skus) == 0 {
continue
if order.Weight <= 5000 { //如果总重量小于5kg就直接发单
var (
goodsNos []string
prices []string
quantities []string
)
err = changeOrderStatus(order.VendorOrderID, model.OrderStatusDelivering, "")
for _, v := range orderSkus {
skus, err := dao.GetSkus(db, []int{v.SkuID}, nil, nil, nil, nil)
if err != nil || len(skus) == 0 {
continue
}
goodsNos = append(goodsNos, skus[0].EclpID)
prices = append(prices, "0")
quantities = append(quantities, utils.Int2Str(v.Count))
}
result, err := api.JdEclpAPI.AddOrder(&jdeclpapi.AddOrderParam{
IsvUUID: order.VendorOrderID,
IsvSource: jdeclpapi.IsvSource,
ShopNo: jdeclpapi.ShopNo,
DepartmentNo: jdeclpapi.DepartmentNo,
WarehouseNo: jdeclpapi.WarehouseNo,
SalesPlatformOrderNo: order.VendorOrderID,
SalePlatformSource: jdeclpapi.SalePlatformSource,
ConsigneeName: order.ConsigneeName,
ConsigneeMobile: order.ConsigneeMobile,
ConsigneeAddress: order.ConsigneeAddress,
OrderMark: jdeclpapi.OrderMark,
GoodsNo: strings.Join(goodsNos, ","),
Price: strings.Join(prices, ","),
Quantity: strings.Join(quantities, ","),
})
if err != nil {
return err
}
order.EclpOutID = result
dao.UpdateEntity(db, order, "EclpOutID")
waybill := &model.Waybill{
VendorOrderID: order.VendorOrderID,
OrderVendorID: model.VendorIDJX,
VendorWaybillID: order.EclpOutID,
WaybillVendorID: model.VendorIDJDWL,
Status: model.WaybillStatusDelivering,
WaybillCreatedAt: time.Now(),
StatusTime: time.Now(),
WaybillFinishedAt: utils.DefaultTimeValue,
}
dao.CreateEntity(db, waybill)
} else { //如果重量超过5kg则需要进行拆单分包商品分包规则。最后一个包不超过5kg,其他包不超过3kg
jxOrder := &JxOrderInfo{}
jxOrder.StoreID = order.StoreID
var skus []*JxSkuInfo
for _, v := range orderSkus {
sku := &JxSkuInfo{}
sku.SkuID = v.SkuID
sku.SalePrice = v.SalePrice
sku.Name = v.SkuName
sku.Weight = v.Weight
sku.Count = v.Count
skus = append(skus, sku)
}
jxOrder.Skus = skus
outOrders, _, _ := tryToSplitMatterOrder(jxOrder)
for _, v := range outOrders {
outJxOrder, deliveryAddress, err := generateOrder(jxcontext.AdminCtx, v, order.AddressID, order.FromStoreID)
if err != nil {
return err
}
if outJxOrder.TotalPrice != v.TotalPrice {
return fmt.Errorf("商品或配送信息发生改变,请重新下单")
}
outJxOrder.OrderID = GenOrderNo(jxcontext.AdminCtx)
order2, err2 := jxOrder2GoodsOrder(jxcontext.AdminCtx, outJxOrder, deliveryAddress)
if err = err2; err == nil {
order2.AddressID = order.AddressID
order2.Status = model.OrderStatusDelivering
callNewOrder(order2)
}
}
//刷新一下库存
for _, v := range goods[0].Skus {
cms.RefreshMatterStock(jxcontext.AdminCtx, v.SkuID)
}
goodsNos = append(goodsNos, skus[0].EclpID)
prices = append(prices, "0")
quantities = append(quantities, utils.Int2Str(v.Count))
}
result, err := api.JdEclpAPI.AddOrder(&jdeclpapi.AddOrderParam{
IsvUUID: order.VendorOrderID,
IsvSource: jdeclpapi.IsvSource,
ShopNo: jdeclpapi.ShopNo,
DepartmentNo: jdeclpapi.DepartmentNo,
WarehouseNo: jdeclpapi.WarehouseNo,
SalesPlatformOrderNo: order.VendorOrderID,
SalePlatformSource: jdeclpapi.SalePlatformSource,
ConsigneeName: order.ConsigneeName,
ConsigneeMobile: order.ConsigneeMobile,
ConsigneeAddress: order.ConsigneeAddress,
OrderMark: jdeclpapi.OrderMark,
GoodsNo: strings.Join(goodsNos, ","),
Price: strings.Join(prices, ","),
Quantity: strings.Join(quantities, ","),
})
if err != nil {
return err
}
order.EclpOutID = result
dao.UpdateEntity(db, order, "EclpOutID")
waybill := &model.Waybill{
VendorOrderID: order.VendorOrderID,
OrderVendorID: model.VendorIDJX,
VendorWaybillID: order.EclpOutID,
WaybillVendorID: model.VendorIDJDWL,
Status: model.WaybillStatusDelivering,
WaybillCreatedAt: time.Now(),
StatusTime: time.Now(),
WaybillFinishedAt: utils.DefaultTimeValue,
}
dao.CreateEntity(db, waybill)
// } else { //如果重量超过5kg则需要进行拆单分包商品分包规则。最后一个包不超过5kg,其他包不超过3kg
// }
//刷新一下库存
for _, v := range goods[0].Skus {
cms.RefreshMatterStock(jxcontext.AdminCtx, v.SkuID)
}
}
return err
@@ -1269,3 +1246,102 @@ func GetMatterOrderStatus(ctx *jxcontext.Context, vendorOrderID string) (result
}
return result, err
}
func tryToSplitMatterOrder(jxOrder *JxOrderInfo) (outOrders []*JxOrderInfo, freightPrice int, err error) {
var (
skus = jxOrder.Skus
weightList []*JxSkuInfo2
flag = true
)
for _, v := range skus {
for i := 0; i < v.Count; i++ {
var sku2 = &JxSkuInfo2{}
sku2.Count = v.Count
sku2.Name = v.Name
sku2.Price = v.Price
sku2.SalePrice = v.SalePrice
sku2.Weight = v.Weight
sku2.SkuID = v.SkuID
weightList = append(weightList, sku2)
}
}
for i := 0; i < len(weightList)-1; i++ {
for j := 0; j < len(weightList)-i-1; j++ {
if weightList[j].Weight < weightList[j+1].Weight {
tmp := weightList[j]
weightList[j] = weightList[j+1]
weightList[j+1] = tmp
}
}
}
for {
outOrders = append(outOrders, loop(weightList, jxOrder, flag))
for i := 0; i < len(weightList); {
if weightList[i].GroupSign {
var weightList3 []*JxSkuInfo2
weightList3 = append(weightList[:i], weightList[i+1:]...)
weightList = weightList3
} else {
i++
}
}
flag = false
if len(weightList) == 0 {
break
}
}
for _, v := range outOrders {
if v.Weight <= 2000 {
freightPrice += 500
} else {
freightPrice += int(utils.Float64TwoInt64(500 + math.Ceil((utils.Int2Float64(v.Weight)-2000)/1000)*200))
}
}
return outOrders, freightPrice, err
}
func loop(weightList []*JxSkuInfo2, jxOrder *JxOrderInfo, flag bool) (outOrder *JxOrderInfo) {
outOrder = &JxOrderInfo{}
outOrder.StoreID = jxOrder.StoreID
sum5 := 0
sum3 := 0
for i := 0; i < len(weightList); i++ {
if flag {
if weightList[i].Weight+sum5 <= 5 {
sum5 += weightList[i].Weight
weightList[i].GroupSign = true
outOrder.Weight += weightList[i].Weight
outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i]))
} else {
if sum5 >= 5 {
break
}
continue
}
} else {
if weightList[i].Weight+sum3 <= 3 {
sum3 += weightList[i].Weight
weightList[i].GroupSign = true
outOrder.Weight += weightList[i].Weight
outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i]))
} else {
if sum3 >= 3 {
break
}
continue
}
}
}
return outOrder
}
func jxOrderChange(sku2 *JxSkuInfo2) *JxSkuInfo {
sku := &JxSkuInfo{}
sku.Count = sku2.Count
sku.Name = sku2.Name
sku.Price = sku2.Price
sku.SalePrice = sku2.SalePrice
sku.SkuID = sku2.SkuID
sku.Weight = sku2.Weight
return sku
}