package delivery import ( "fmt" "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)) } }