package fn import ( "fmt" "strings" "time" "git.rosy.net.cn/baseapi/utils" beego "github.com/astaxie/beego/adapter" "github.com/astaxie/beego/adapter/orm" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/partner/delivery" "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/baseapi/platformapi/fnpsapi" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals/api" ) const ( ComplaintReasonsFn150 = 150 //:未保持餐品完整, ComplaintReasonsFn220 = 220 //:少餐错餐, ComplaintReasonsFn160 = 160 //:服务态度恶劣, ComplaintReasonsFn190 = 190 //:额外索取费用, ComplaintReasonsFn170 = 170 //:诱导收货人或商户退单, ComplaintReasonsFn140 = 140 //:提前点击送达, ComplaintReasonsFn210 = 210 //:虚假标记异常, ComplaintReasonsFn200 = 200 //:虚假点击配送成功, ComplaintReasonsFn130 = 130 //:未进行配送,导致订单失败或取消, ComplaintReasonsFn120 = 120 //:配送超时 ) var ( curDeliveryHandler *DeliveryHandler complaintReson2FnResonMap = map[int]int{ model.ComplaintReasons1: ComplaintReasonsFn160, model.ComplaintReasons2: ComplaintReasonsFn130, model.ComplaintReasons3: ComplaintReasonsFn130, model.ComplaintReasons4: ComplaintReasonsFn120, model.ComplaintReasons5: ComplaintReasonsFn130, model.ComplaintReasons6: ComplaintReasonsFn150, model.ComplaintReasons7: ComplaintReasonsFn190, model.ComplaintReasons69: ComplaintReasonsFn170, model.ComplaintReasons71: ComplaintReasonsFn140, } ) type DeliveryHandler struct { } func init() { if api.FnAPI != nil { curDeliveryHandler = new(DeliveryHandler) partner.RegisterDeliveryPlatform(curDeliveryHandler, true) } } func (c *DeliveryHandler) GetVendorID() int { return model.VendorIDFengNiao } func (c *DeliveryHandler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) { err = api.FnAPI.CancelOrder(&fnpsapi.CancelOrderParam{ PartnerOrderCode: bill.VendorOrderID, OrderCancelReasonCode: 1, //用户取消 OrderCancelCode: fnpsapi.OrderCancelReson8, OrderCancelTime: time.Now().UnixNano() / 1e6, }) if err != nil { if strings.Contains(err.Error(), "运单暂未生成") { err = nil } } bill.Status = model.WaybillStatusCanceled bill.Remark = cancelReason partner.CurOrderManager.OnWaybillStatusChanged(bill) return err } func (c *DeliveryHandler) ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) { err = api.FnAPI.ComplaintRider(bill.VendorOrderID, complaintReson2FnResonMap[resonID]) return err } func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) { var ( db = dao.GetDB() ) if vendorOrgCode, err := dao.GetVendorOrgCode(db, model.VendorIDFengNiao, "", model.VendorOrgTypeDelivery); err == nil { if len(vendorOrgCode) > 0 { if vendorOrgCode[0].IsOpen == model.YES { return nil, fmt.Errorf("此平台配送已被系统关闭,暂不发配送 [%v]", vendorOrgCode[0].Comment) } } } else { return nil, err } storeDetail, err := dao.GetStoreDetail(db, order.StoreID, order.VendorID, order.VendorOrgCode) deliveryFee, _, err := delivery.CalculateOrderDeliveryFee(order, time.Now(), db) if err == nil { if err = delivery.CallCreateWaybillPolicy(deliveryFee, maxDeliveryFee, order, model.VendorIDFengNiao); err != nil { return nil, err } params := &fnpsapi.CreateOrderParam{ PartnerOrderCode: order.VendorOrderID, NotifyURL: globals.FnNotifyURL, ChainStoreCode: utils.Int2Str(jxutils.GetSaleStoreIDFromOrder(order)), OrderType: 1, //即时达 TransportInfo: &fnpsapi.TransportInfo{ TransportName: order.StoreName, TransportAddress: storeDetail.Address, TransportLongitude: jxutils.IntCoordinate2Standard(storeDetail.Lng), TransportLatitude: jxutils.IntCoordinate2Standard(storeDetail.Lat), PositionSource: 3, TransportTel: storeDetail.Tel1, }, OrderAddTime: order.OrderCreatedAt.UnixNano() / 1e6, OrderTotalAmount: jxutils.IntPrice2Standard(order.SalePrice), OrderActualAmount: jxutils.IntPrice2Standard(order.ActualPayPrice), OrderWeight: float64(jxutils.IntWeight2Float(order.Weight)), OrderRemark: utils.FilterMb4("客户电话:" + order.ConsigneeMobile + "," + order.BuyerComment + ",取货失败或配送遇到问题请联系18048531223,禁止未配送直接完成定单!"), IsInvoiced: 0, OrderPaymentStatus: 1, OrderPaymentMethod: 1, IsAgentPayment: 0, GoodsCount: order.GoodsCount, ReceiverInfo: &fnpsapi.ReceiverInfo{ ReceiverName: order.ConsigneeName, ReceiverAddress: order.ConsigneeAddress, ReceiverLongitude: jxutils.IntCoordinate2Standard(order.ConsigneeLng), ReceiverLatitude: jxutils.IntCoordinate2Standard(order.ConsigneeLat), ReceiverPrimaryPhone: order.ConsigneeMobile, ReceiverSecondPhone: order.ConsigneeMobile2, PositionSource: 3, }, SerialNumber: model.VendorNames[order.VendorID] + " #" + utils.Int2Str(order.OrderSeq), } var skuInfo []*fnpsapi.ItemsJSON for _, v := range order.Skus { skuInfo = append(skuInfo, &fnpsapi.ItemsJSON{ ItemID: utils.Int2Str(v.SkuID), ItemName: v.SkuName, ItemQuantity: v.Count, ItemPrice: jxutils.IntPrice2Standard(v.SalePrice), ItemActualPrice: jxutils.IntPrice2Standard(v.SalePrice), }) } params.ItemsJSON = skuInfo //要求饿百的订单要传来源 if order.VendorID == model.VendorIDEBAI { params.OrderSource = "109" params.ChannelOrderCode = order.VendorOrderID } err = api.FnAPI.CreateOrder(params) if err == nil { bill = &model.Waybill{ VendorOrderID: order.VendorOrderID, OrderVendorID: order.VendorID, VendorWaybillID: "", VendorWaybillID2: "", WaybillVendorID: model.VendorIDFengNiao, DesiredFee: deliveryFee, } delivery.OnWaybillCreated(bill) } else { globals.SugarLogger.Debugf("CreateWaybill failed, orderID:%s, billParams:%v, error:%v", order.VendorOrderID, params, err) } } return bill, err } func (c *DeliveryHandler) getMTPSShopID(order *model.GoodsOrder, db *dao.DaoDB) (retVal string, err error) { saleStoreID := jxutils.GetSaleStoreIDFromOrder(order) storeCourierList, err2 := dao.GetOpenedStoreCouriersByStoreID(db, saleStoreID, model.VendorIDFengNiao) if err = err2; err != nil && err != orm.ErrNoRows { return "", err } if len(storeCourierList) == 0 { return "", partner.ErrStoreHaveNoCourier } retVal = storeCourierList[0].VendorStoreID if beego.BConfig.RunMode == "dev" { retVal = "test_0001" } return retVal, nil } func (c *DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) { db := dao.GetDB() deliveryFeeInfo = &partner.WaybillFeeInfo{} deliveryFeeInfo.RefDeliveryFee, deliveryFeeInfo.RefAddFee, err = delivery.CalculateOrderDeliveryFee(order, time.Now(), db) if err == nil { if _, err = c.getMTPSShopID(order, db); err == nil { deliveryFeeInfo.DeliveryFee = deliveryFeeInfo.RefDeliveryFee } } return deliveryFeeInfo, err } func OnWaybillMsg(msg *fnpsapi.WayBillInfo) { order := &model.Waybill{ VendorWaybillID: utils.Int64ToStr(msg.OpenOrderCode), VendorWaybillID2: msg.PartnerOrderCode, WaybillVendorID: model.VendorIDFengNiao, CourierName: msg.CarrierDriverName, CourierMobile: msg.CarrierDriverPhone, VendorStatus: utils.Int2Str(msg.OrderStatus), StatusTime: utils.Timestamp2Time(msg.PushTime), Remark: msg.Description, } order.VendorOrderID, order.OrderVendorID = jxutils.SplitUniversalOrderID(msg.PartnerOrderCode) switch msg.OrderStatus { case fnpsapi.OrderStatusAccept: order.Status = model.WaybillStatusNew case fnpsapi.OrderStatusAssigned: order.DesiredFee = GetDesiredFee(order.VendorOrderID) order.Status = model.WaybillStatusAccepted order.Remark = order.CourierName + "," + order.CourierMobile case fnpsapi.OrderStatusArrived: order.DesiredFee = GetDesiredFee(order.VendorOrderID) order.Status = model.WaybillStatusCourierArrived case fnpsapi.OrderStatusDelivering: order.Status = model.WaybillStatusDelivering case fnpsapi.OrderStatusDelivered: order.Status = model.WaybillStatusDelivered case fnpsapi.OrderStatusException: order.Status = model.WaybillStatusDeliverFailed default: globals.SugarLogger.Warnf("onWaybillMsg unknown msg:%v", msg) } partner.CurOrderManager.OnWaybillStatusChanged(order) } func GetDesiredFee(vendorOrderID string) (desiredFee int64) { if result, err := api.FnAPI.QueryOrder(vendorOrderID); err == nil { return jxutils.StandardPrice2Int(result.OrderTotalDeliveryCost) } return desiredFee }