diff --git a/business/controller/mtps/waybill.go b/business/controller/mtps/waybill.go index 76d2fc036..2c13319e9 100644 --- a/business/controller/mtps/waybill.go +++ b/business/controller/mtps/waybill.go @@ -3,6 +3,7 @@ package mtps import ( "errors" "math" + "time" "git.rosy.net.cn/baseapi/platformapi/mtpsapi" "git.rosy.net.cn/baseapi/utils" @@ -16,8 +17,13 @@ import ( "github.com/astaxie/beego/orm" ) +const ( + maxAddFee = 200 // 最大增加费用,单位为分,超过不发美团了 +) + var ( ErrCanNotFindMTPSStore = errors.New("不能找到美团配送站点配置") + ErrAddFeeExceeded = errors.New("美团配送超过基准价太多") ) type WaybillController struct { @@ -58,7 +64,7 @@ func (c *WaybillController) onWaybillMsg(msg *mtpsapi.CallbackOrderMsg) (retVal case mtpsapi.OrderStatusWaitingForSchedule: order.Status = model.WaybillStatusNew case mtpsapi.OrderStatusAccepted: - order.DesiredFee = c.calculateDeliveryFee(order) + order.DesiredFee, _ = c.calculateBillDeliveryFee(order) order.Status = model.WaybillStatusAccepted case mtpsapi.OrderStatusPickedUp: order.Status = model.WaybillStatusDelivering @@ -87,14 +93,11 @@ func (c *WaybillController) callbackMsg2Waybill(msg *mtpsapi.CallbackOrderMsg) ( return retVal } -func (c *WaybillController) calculateDeliveryFee(bill *model.Waybill) (retVal int64) { - order, err := controller.OrderManager.LoadOrder(bill.VendorOrderID, bill.OrderVendorID) - if err != nil { - return 0 - } - +func (c *WaybillController) calculateOrderDeliveryFee(order *model.GoodsOrder, billTime time.Time, db orm.Ormer) (delieveryFee, addFee int64) { var lists []orm.ParamsList - db := orm.NewOrm() + if db == nil { + db = orm.NewOrm() + } JxStoreID := jxutils.GetJxStoreIDFromOrder(order) num, err := db.Raw(` SELECT t2.price, t1.lng, t1.lat @@ -103,12 +106,11 @@ func (c *WaybillController) calculateDeliveryFee(bill *model.Waybill) (retVal in WHERE t1.storeid = ? `, JxStoreID).ValuesList(&lists) - var delieveryFee int64 if err == nil && num == 1 { delieveryFee = utils.Str2Int64(lists[0][0].(string)) } else { globals.SugarLogger.Warnf("calculateDeliveryFee can not calculate delivery fee for orderID:%s, num:%d, error:%v", order.VendorOrderID, num, err) - return 0 + return 0, 0 } lng := utils.Str2Float64(lists[0][1].(string)) @@ -118,76 +120,90 @@ func (c *WaybillController) calculateDeliveryFee(bill *model.Waybill) (retVal in distance := jxutils.EarthDistance(lat, lng, lat2, lng2) * 1.4 if distance < 3 { } else if distance < 5 { - delieveryFee += jxutils.StandardPrice2Int(math.Ceil(distance - 3)) + addFee += jxutils.StandardPrice2Int(math.Ceil(distance - 3)) } else { - delieveryFee += jxutils.StandardPrice2Int(2 + 2*math.Ceil(distance-5)) + addFee += jxutils.StandardPrice2Int(2 + 2*math.Ceil(distance-5)) } if order.Weight < 5*1000 { } else if order.Weight < 10*1000 { - delieveryFee += jxutils.StandardPrice2Int(0.5 * float64(order.Weight/1000-5)) + addFee += jxutils.StandardPrice2Int(0.5 * float64(order.Weight/1000-5)) } else if order.Weight < 20*1000 { - delieveryFee += jxutils.StandardPrice2Int(2.5 + 1*float64(order.Weight/1000-10)) + addFee += jxutils.StandardPrice2Int(2.5 + 1*float64(order.Weight/1000-10)) } else { - delieveryFee += jxutils.StandardPrice2Int(2.5 + 10 + 2*float64(order.Weight/1000-20)) + addFee += jxutils.StandardPrice2Int(2.5 + 10 + 2*float64(order.Weight/1000-20)) } - hour, min, sec := bill.StatusTime.Clock() + hour, min, sec := billTime.Clock() totalSeconds := hour*3600 + min*60 + sec if totalSeconds >= 11*3600+30*60 && totalSeconds <= 13*3600 { // 11:30 -- 13:00 - delieveryFee += jxutils.StandardPrice2Int(3) + addFee += jxutils.StandardPrice2Int(3) } else if totalSeconds >= 21*3600 || totalSeconds <= 6*3600 { // 21:00 -- 06:00 - delieveryFee += jxutils.StandardPrice2Int(3) + addFee += jxutils.StandardPrice2Int(3) } - return delieveryFee + return delieveryFee + addFee, addFee +} + +func (c *WaybillController) calculateBillDeliveryFee(bill *model.Waybill) (delieveryFee, addFee int64) { + order, err := controller.OrderManager.LoadOrder(bill.VendorOrderID, bill.OrderVendorID) + if err != nil { + return 0, 0 + } + return c.calculateOrderDeliveryFee(order, bill.StatusTime, nil) } // DeliveryPlatformHandler func (c *WaybillController) CreateWaybill(order *model.GoodsOrder) (err error) { db := orm.NewOrm() - // 忽略坐标转换错误,即使是转换出错,也只能当成转换成功来处理,底层会有错误日志输出 - lngFloat, latFloat, _ := jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType) - billParams := &mtpsapi.CreateOrderByShopParam{ - OrderID: jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID), - DeliveryServiceCode: mtpsapi.DeliveryServiceCodeRapid, - ReceiverName: order.ConsigneeName, - ReceiverAddress: order.ConsigneeAddress, - ReceiverPhone: order.ConsigneeMobile, - CoordinateType: model.CoordinateTypeMars, - ReceiverLng: jxutils.StandardCoordinate2Int(lngFloat), - ReceiverLat: jxutils.StandardCoordinate2Int(latFloat), - GoodsValue: jxutils.IntPrice2Standard(order.SalePrice), // todo 超价处理 - GoodsWeight: float64(order.Weight) / 1000, - // ExpectedDeliveryTime: order.ExpectedDeliveredTime.Unix(), - OrderType: mtpsapi.OrderTypeASAP, - } - if billParams.DeliveryID, err = c.getDeliveryID(order, db); err == nil { - if billParams.ShopID, err = c.getMTPSShopID(order, db); err == nil { - globals.SugarLogger.Debug(billParams.ShopID) - goods := &mtpsapi.GoodsDetail{ - Goods: []*mtpsapi.GoodsItem{}, - } - goodItemMap := map[string]*mtpsapi.GoodsItem{} - for _, sku := range order.Skus { - goodItem := &mtpsapi.GoodsItem{ - GoodCount: sku.Count, - GoodPrice: jxutils.IntPrice2Standard(sku.SalePrice), + _, addFee := c.calculateOrderDeliveryFee(order, time.Now(), db) + if addFee <= maxAddFee { + // 忽略坐标转换错误,即使是转换出错,也只能当成转换成功来处理,底层会有错误日志输出 + lngFloat, latFloat, _ := jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType) + billParams := &mtpsapi.CreateOrderByShopParam{ + OrderID: jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID), + DeliveryServiceCode: mtpsapi.DeliveryServiceCodeRapid, + ReceiverName: order.ConsigneeName, + ReceiverAddress: order.ConsigneeAddress, + ReceiverPhone: order.ConsigneeMobile, + CoordinateType: model.CoordinateTypeMars, + ReceiverLng: jxutils.StandardCoordinate2Int(lngFloat), + ReceiverLat: jxutils.StandardCoordinate2Int(latFloat), + GoodsValue: jxutils.IntPrice2Standard(order.SalePrice), // todo 超价处理 + GoodsWeight: float64(order.Weight) / 1000, + // ExpectedDeliveryTime: order.ExpectedDeliveredTime.Unix(), + OrderType: mtpsapi.OrderTypeASAP, + } + if billParams.DeliveryID, err = c.getDeliveryID(order, db); err == nil { + if billParams.ShopID, err = c.getMTPSShopID(order, db); err == nil { + globals.SugarLogger.Debug(billParams.ShopID) + goods := &mtpsapi.GoodsDetail{ + Goods: []*mtpsapi.GoodsItem{}, } - goodItem.GoodName, goodItem.GoodUnit = jxutils.SplitSkuName(sku.SkuName) - // 好像SKU名不能重复,否则会报错,尝试处理一下 - if item, ok := goodItemMap[goodItem.GoodName]; !ok { - goods.Goods = append(goods.Goods, goodItem) - goodItemMap[goodItem.GoodName] = goodItem - } else { - item.GoodCount += goodItem.GoodCount + goodItemMap := map[string]*mtpsapi.GoodsItem{} + for _, sku := range order.Skus { + goodItem := &mtpsapi.GoodsItem{ + GoodCount: sku.Count, + GoodPrice: jxutils.IntPrice2Standard(sku.SalePrice), + } + goodItem.GoodName, goodItem.GoodUnit = jxutils.SplitSkuName(sku.SkuName) + // 好像SKU名不能重复,否则会报错,尝试处理一下 + if item, ok := goodItemMap[goodItem.GoodName]; !ok { + goods.Goods = append(goods.Goods, goodItem) + goodItemMap[goodItem.GoodName] = goodItem + } else { + item.GoodCount += goodItem.GoodCount + } + } + addParams := utils.Params2Map("note", order.BuyerComment, "goods_detail", string(utils.MustMarshal(goods))) + _, err = api.MtpsAPI.CreateOrderByShop(billParams, addParams) + if err != nil { + globals.SugarLogger.Debugf("CreateWaybill, orderID:%s, billParams:%v, addParams:%v", order.VendorOrderID, billParams, addParams) } - } - addParams := utils.Params2Map("note", order.BuyerComment, "goods_detail", string(utils.MustMarshal(goods))) - _, err = api.MtpsAPI.CreateOrderByShop(billParams, addParams) - if err != nil { - globals.SugarLogger.Debugf("CreateWaybill, orderID:%s, billParams:%v, addParams:%v", order.VendorOrderID, billParams, addParams) } } + } else { + err = ErrAddFeeExceeded + globals.SugarLogger.Infof("CreateWaybill addFee exceeded too much, it's %d", addFee) } return err }