Files
jx-callback/business/partner/delivery/delivery.go
邹宗楠 c52abc3526 1
2022-04-15 18:56:09 +08:00

222 lines
8.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package delivery
import (
"fmt"
"git.rosy.net.cn/baseapi/platformapi/mtpsapi"
"math"
"time"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
)
const (
warningDistance = 10 // 公里
warningWeight = 50 * 1000 // 克
// maxDiffFee2Mtps = 200 // 与美团配送最多差价
// maxAddFee = 200 // 最大增加费用,单位为分,超过不发三方配送了
defMaxDeliveryFee = 10000 // 创建运单最高价
alarmFee = 1500 // 配送费报警阈值
)
func CallCreateWaybillPolicy(deliveryFee, maxDeliveryFee int64, order *model.GoodsOrder, waybillVendorID int) (err error) {
if maxDeliveryFee <= 0 || maxDeliveryFee > defMaxDeliveryFee {
maxDeliveryFee = defMaxDeliveryFee
}
if deliveryFee > maxDeliveryFee {
errStr := fmt.Sprintf("超最高限价, 所需运费:%s, 最高限价:%s", jxutils.IntPrice2StandardCurrencyString(deliveryFee), jxutils.IntPrice2StandardCurrencyString(maxDeliveryFee))
err = fmt.Errorf(errStr)
globals.SugarLogger.Debugf("CallCreateWaybillPolicy orderID:%s, 平台:%s运单创建出错:%s", order.VendorOrderID, model.VendorChineseNames[waybillVendorID], errStr)
}
return err
}
func CalculateDeliveryFee(db *dao.DaoDB, jxStoreID int, hint string, consigneeLng, consigneeLat, coordinateType, weight int, billTime time.Time) (deliveryFee, addFee int64, err error) {
globals.SugarLogger.Debugf("CalculateOrderDeliveryFee orderID:%s", hint)
if db == nil {
db = dao.GetDB()
}
var lng, lat float64
priceInfo := &struct {
CityPrice int64
DistrictPrice int64
Lng int
Lat int
}{}
if err = dao.GetRow(db, priceInfo, `
SELECT
t2.mtps_price city_price, t2.mtps_price district_price, t1.lng, t1.lat
FROM store t1
LEFT JOIN place t2 ON t2.level = 2 AND t2.code = t1.city_code
LEFT JOIN place t3 ON t3.level = 3 AND t2.code = t1.district_code
WHERE t1.id = ? AND t1.deleted_at = ?
`, jxStoreID, utils.DefaultTimeValue); err != nil {
return 0, 0, err
}
lng = jxutils.IntCoordinate2Standard(priceInfo.Lng)
lat = jxutils.IntCoordinate2Standard(priceInfo.Lat)
if deliveryFee = priceInfo.DistrictPrice; deliveryFee == 0 {
deliveryFee = priceInfo.CityPrice
}
if deliveryFee == 0 {
// globals.SugarLogger.Warnf("CalculateOrderDeliveryFee 查不到美团配送价格 orderID:%s", hint)
deliveryFee = 650
}
if lng == 0 || lat == 0 {
globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,门店:%d没有坐标信息", hint, jxStoreID)
return 0, 0, fmt.Errorf("找不到门店:%d的坐标", jxStoreID)
}
lng2, lat2, _ := jxutils.IntCoordinate2MarsStandard(consigneeLng, consigneeLat, coordinateType)
var distanceAddFee, weightAddFee, timeAddFee int64
// 距离加价
distance := jxutils.WalkingDistance(lng, lat, lng2, lat2)
if distance > warningDistance {
//globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,距离%.3fkm太远,请检查门店坐标信息", hint, distance)
}
distanceAddFee = int64(jxutils.CalcStageValue([][]float64{
[]float64{
7,
300,
},
[]float64{
5,
200,
},
[]float64{
3,
100,
},
}, distance))
// 重量加价
if weight > warningWeight {
//globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,重量:%dg太重,请检查商品属性", hint, weight)
}
weightAddFee = int64(jxutils.CalcStageValue([][]float64{
[]float64{
20,
200,
},
[]float64{
10,
100,
},
[]float64{
5,
50,
},
}, float64(weight)/1000))
// 其它加价
hour, min, sec := billTime.Clock()
totalSeconds := hour*3600 + min*60 + sec
// 午高峰加价
if totalSeconds >= 11*3600 && totalSeconds <= 14*3600 { // 11:00 -- 14:00
timeAddFee = jxutils.StandardPrice2Int(2)
} else if totalSeconds >= 21*3600 || totalSeconds <= 6*3600 { // 21:00 -- 06:00 夜间加价
timeAddFee = jxutils.StandardPrice2Int(3)
}
addFee = distanceAddFee + weightAddFee + timeAddFee
globals.SugarLogger.Debugf("CalculateOrderDeliveryFee orderID:%s, deliveryFee:%d addFee:%d, distance:%.3fkm distanceAddFee:%d, weight:%dg weightAddFee:%d, time:%s timeAddFee:%d",
hint, deliveryFee, addFee, distance, distanceAddFee, weight, weightAddFee, utils.Time2TimeStr(billTime), timeAddFee)
return deliveryFee + addFee, addFee, nil
}
func CalculateOrderDeliveryFee(order *model.GoodsOrder, billTime time.Time, db *dao.DaoDB) (deliveryFee, addFee int64, err error) {
return CalculateDeliveryFee(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorOrderID, order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType, order.Weight, billTime)
}
func CalculateBillDeliveryFee(bill *model.Waybill) (deliveryFee, addFee int64) {
order, err := partner.CurOrderManager.LoadOrder(bill.VendorOrderID, bill.OrderVendorID)
if err != nil {
return 0, 0
}
deliveryFee, addFee, _ = CalculateOrderDeliveryFee(order, bill.StatusTime, nil)
return deliveryFee, addFee
}
// 日志提示检查订单运费
func OnWaybillCreated(waybill *model.Waybill) {
deliveryFee := int64(math.Max(float64(waybill.DesiredFee), float64(waybill.ActualFee)))
if deliveryFee > alarmFee {
globals.SugarLogger.Infof("[运营]%s订单, orderID:%s, 成功创建%s运单:%s, 配送费:%s太高(大于%s),请知悉!", model.VendorChineseNames[waybill.OrderVendorID], waybill.VendorOrderID,
model.VendorChineseNames[waybill.WaybillVendorID], waybill.VendorWaybillID, jxutils.IntPrice2StandardCurrencyString(deliveryFee), jxutils.IntPrice2StandardCurrencyString(alarmFee))
}
}
// 订单骑手信息推送:将获取到的三方配送订单,且订单状态为配送中的订单,将配送人员的信息返回给订单方
// 该方法为定时任务,没五分钟推送一次订单消息,订单状态发生变化时
//配送状态code如下提供配送状态枚举值
//以及各配送状态对应在C端用户端和B端商家PC端后台展示的配送状态信息。
//未同步配送状态时C端商家已接单B端待发配送
//0-配送单发往配送C端商家已接单B端待骑手接单
//1-已创建配送包裹C端商家已接单B端待骑手接单
//5-已分配骑手C端商家已接单B端已分配骑手
//10-骑手已接单C端骑手正在赶往商家B端待骑手取货
//15-骑手已到店C端骑手到店取货中B端骑手已到店
//20-骑手已取货C端商品配送中/骑手正在送货B端骑手已取货
//40-骑手已送达C端商品已送达B端骑手已送达
//100-配送单已取消C端商家已接单B端配送已取消
//注:若同步配送状态为“配送单已取消”,接口仍支持继续同步配送状态。 说明商家如未上传此信息则平台默认值为20现已要求必传
func GetOrderRiderInfoToPlatform(orderId string) {
params := make(map[string]interface{}, 0)
params["brandID"] = 0
params["statuss"] = 20
params["isDateFinish"] = false
params["isIncludeFake"] = true
params["mustInvoice"] = false
params["adjustCount"] = 0
params["waybillVendorIDs"] = `[101,102,103]`
if orderId != "" { // 订单id会忽略其他参数
params["keyword"] = orderId
}
//params["offset"] = 0
//params["pageSize"] = 10000
// 查询三天内一万条数据
orders, _, err := dao.GetOrders(dao.GetDB(), nil, false, true, time.Now().Add(-24*3*time.Hour).Format("2006-01-02"), time.Now().Format("2006-01-02"), false, nil, false, "", params, 0, 10000)
if err != nil {
globals.SugarLogger.Errorf("GetOrder err :%v", err)
return
}
for _, v := range orders {
var riderInfo *mtpsapi.RiderInfo
if handlerInfo := partner.GetDeliveryPlatformFromVendorID(v.WaybillVendorID); handlerInfo != nil {
riderInfo, err = handlerInfo.Handler.GetRiderInfo(v.VendorOrderID, utils.Str2Int64(v.VendorWaybillId2Waybill), v.VendorWaybillID)
if err != nil {
globals.SugarLogger.Errorf("Get Order waybill rider info err :%v", err)
continue
}
}
// 目前只推送美团骑手信息
switch v.VendorID {
case model.VendorIDMTWM: // 美团发单
paramsMap := utils.Struct2Map(riderInfo, "", true)
if handler := partner.GetPurchaseOrderHandlerFromVendorID(v.VendorID); handler != nil {
if err := handler.GetOrderRider(v.VendorOrgCode, v.VendorOrderID, paramsMap); err != nil {
globals.SugarLogger.Errorf("Error pushing meituan rider information :%v", err)
}
}
case model.VendorIDELM: // 饿了么
case model.VendorIDEBAI: // 饿百发单
case model.VendorIDJD: // 京东发单
case model.VendorIDGD: // 美团发单
case model.VendorIDYB: // 银豹发单
case model.VendorIDJDShop: // 京东商城
case model.VendorIDWSC: // 微盟微商城
default:
globals.SugarLogger.Errorf("Order source error, non system order")
return
}
}
return
}