package ebai import ( "fmt" "strings" "git.rosy.net.cn/baseapi/platformapi/ebaiapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" ) var ( AfsVendorStatus2Status4PartRefundMap = map[int]int{ ebaiapi.OrderPartRefundApply: model.AfsOrderStatusWait4Approve, ebaiapi.OrderPartRefundSuccess: model.AfsOrderStatusFinished, ebaiapi.OrderPartRefundUserApplyArbitration: model.OrderStatusUnknown, // 是否是中间状态 ebaiapi.OrderPartRefundFailed: model.AfsOrderStatusFailed, ebaiapi.OrderPartRefundMerchantRefused: model.AfsOrderStatusFailed, // 是否是中间状态 } AfsVendorStatus2Status4UserCancel = map[int]int{ ebaiapi.OrderUserCancelApply: model.AfsOrderStatusWait4Approve, ebaiapi.OrderUserCancelCSIntervene: model.OrderStatusUnknown, ebaiapi.OrderUserCancelCSRefused: model.AfsOrderStatusFailed, ebaiapi.OrderUserCancelCSAgreed: model.AfsOrderStatusFinished, ebaiapi.OrderUserCancelMerchantRefused: model.AfsOrderStatusFailed, ebaiapi.OrderUserCancelMerchantAgreed: model.AfsOrderStatusFinished, ebaiapi.OrderUserCancelInvalid: model.AfsOrderStatusFailed, } ) func (c *PurchaseHandler) isAfsMsg(msg *ebaiapi.CallbackMsg) bool { if msg.Cmd == ebaiapi.CmdOrderPartRefund { msgType := int(utils.MustInterface2Int64(msg.Body["type"])) return msgType == ebaiapi.OrderPartRefuncTypeCustomer || msgType == ebaiapi.OrderPartRefuncTypeCS } else if msg.Cmd == ebaiapi.CmdOrderUserCancel { cancelType := int(utils.MustInterface2Int64(msg.Body["cancel_type"])) return cancelType == ebaiapi.OrderUserCancelTypeAfterSale } return false } func (c *PurchaseHandler) OnAfsOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) { jxutils.CallMsgHandlerAsync(func() { retVal = c.onAfsOrderMsg(msg) }, jxutils.ComposeUniversalOrderID(GetOrderIDFromMsg(msg), model.VendorIDEBAI)) return retVal } func (c *PurchaseHandler) onAfsOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) { if orderStatus := c.callbackAfsMsg2Status(msg); orderStatus != nil { var err error if orderStatus.Status == model.AfsOrderStatusWait4Approve || orderStatus.Status == model.AfsOrderStatusNew { var afsOrder *model.AfsOrder if msg.Cmd == ebaiapi.CmdOrderPartRefund { partRefundData := msg.Data.(*ebaiapi.CBPartRefundInfo) afsOrder = &model.AfsOrder{ VendorID: model.VendorIDEBAI, AfsOrderID: orderStatus.VendorOrderID, VendorOrderID: orderStatus.RefVendorOrderID, VendorStoreID: "", StoreID: 0, AfsCreatedAt: utils.Timestamp2Time(msg.Timestamp), VendorAppealType: "", AppealType: model.AfsAppealTypeRefund, VendorReasonType: partRefundData.ReasonType, ReasonType: c.convertAfsReasonType(partRefundData.ReasonType), ReasonDesc: utils.LimitUTF8StringLen(buildFullReason(partRefundData.Reason, partRefundData.AdditionReason), 1024), ReasonImgList: utils.LimitUTF8StringLen(strings.Join(partRefundData.Photos, ","), 1024), RefundType: model.AfsTypePartRefund, VendorOrgCode: msg.Source, // FreightUserMoney: afsInfo.OrderFreightMoney, // AfsFreightMoney: afsInfo.AfsFreight, // BoxMoney: afsInfo.PackagingMoney, // TongchengFreightMoney: afsInfo.TongchengFreightMoney, // SkuBoxMoney: afsInfo.MealBoxMoney, } for _, sku := range partRefundData.RefundProducts { orderSku := &model.OrderSkuFinancial{ // VendorID: model.VendorIDEBAI, // AfsOrderID: afsOrder.AfsOrderID, // VendorOrderID: afsOrder.VendorOrderID, // VendorStoreID: afsOrder.VendorStoreID, // StoreID: afsOrder.StoreID, // IsAfsOrder: 1, Count: sku.Number, // ConfirmTime: afsOrder.AfsCreateAt, VendorSkuID: sku.SkuID, SkuID: int(utils.Str2Int64WithDefault(sku.CustomSkuID, 0)), Name: sku.Name, UserMoney: sku.TotalRefund, PmSkuSubsidyMoney: sku.ShopEleRefund, } afsOrder.SkuUserMoney += orderSku.UserMoney afsOrder.PmSubsidyMoney += orderSku.PmSubsidyMoney afsOrder.Skus = append(afsOrder.Skus, orderSku) } } else if msg.Cmd == ebaiapi.CmdOrderUserCancel { if afsOrder = c.createAfsOrder(msg); afsOrder != nil { // if orderFinancial, err2 := partner.CurOrderManager.LoadOrderFinancial(orderStatus.RefVendorOrderID, model.VendorIDEBAI); err2 == nil { // afsOrder = c.OrderFinancialDetail2Refund(orderFinancial, msg) cancelData := msg.Data.(*ebaiapi.CBUserCancelInfo) afsOrder.AfsOrderID = orderStatus.VendorOrderID afsOrder.RefundType = model.AfsTypeFullRefund afsOrder.AppealType = model.AfsAppealTypeRefund afsOrder.VendorReasonType = "" afsOrder.ReasonType = model.AfsReasonNotOthers afsOrder.ReasonDesc = utils.LimitUTF8StringLen(buildFullReason(cancelData.CancelReason, cancelData.AdditionReason), 1024) afsOrder.ReasonImgList = utils.LimitUTF8StringLen(strings.Join(cancelData.Pictures, ","), 1024) } } if afsOrder != nil { err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus) } } else { if afsOrder2, err := partner.CurOrderManager.LoadAfsOrder(orderStatus.VendorOrderID, orderStatus.VendorID); afsOrder2 == nil && err == nil { partRefundData := msg.Data.(*ebaiapi.CBPartRefundInfo) afsOrder := &model.AfsOrder{ VendorID: model.VendorIDEBAI, AfsOrderID: orderStatus.VendorOrderID, VendorOrderID: orderStatus.RefVendorOrderID, VendorStoreID: "", StoreID: 0, AfsCreatedAt: utils.Timestamp2Time(msg.Timestamp), VendorAppealType: "", AppealType: model.AfsAppealTypeRefund, VendorReasonType: partRefundData.ReasonType, ReasonType: c.convertAfsReasonType(partRefundData.ReasonType), ReasonDesc: utils.LimitUTF8StringLen(buildFullReason(partRefundData.Reason, partRefundData.AdditionReason), 1024), ReasonImgList: utils.LimitUTF8StringLen(strings.Join(partRefundData.Photos, ","), 1024), RefundType: model.AfsTypePartRefund, VendorOrgCode: msg.Source, } for _, sku := range partRefundData.RefundProducts { orderSku := &model.OrderSkuFinancial{ Count: sku.Number, VendorSkuID: sku.SkuID, SkuID: int(utils.Str2Int64WithDefault(sku.CustomSkuID, 0)), Name: sku.Name, UserMoney: sku.TotalRefund, PmSkuSubsidyMoney: sku.ShopEleRefund, } afsOrder.SkuUserMoney += orderSku.UserMoney afsOrder.PmSubsidyMoney += orderSku.PmSubsidyMoney afsOrder.Skus = append(afsOrder.Skus, orderSku) } if afsOrder != nil { err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus) } } else { err = partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus) } } retVal = api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil) } return retVal } func (p *PurchaseHandler) createAfsOrder(msg *ebaiapi.CallbackMsg) (afsOrder *model.AfsOrder) { cancelData := msg.Data.(*ebaiapi.CBUserCancelInfo) afsOrder, err := partner.CurOrderManager.CreateAfsOrderFromOrder(utils.Int64ToStr(cancelData.OrderID), model.VendorIDEBAI) if err == nil { afsOrder.AfsOrderID = afsOrder.VendorOrderID afsOrder.AfsCreatedAt = utils.Timestamp2Time(msg.Timestamp) } else { afsOrder = nil } return afsOrder } func (c *PurchaseHandler) convertAfsReasonType(vendorReasonType string) int8 { return model.AfsReasonNotOthers } func (c *PurchaseHandler) GetAfsStatusFromVendorStatus4PartRefund(vendorStatus int) int { return AfsVendorStatus2Status4PartRefundMap[vendorStatus] } func (c *PurchaseHandler) GetAfsStatusFromVendorStatus4UserCancel(vendorStatus int) int { return AfsVendorStatus2Status4UserCancel[vendorStatus] } func (c *PurchaseHandler) callbackAfsMsg2Status(msg *ebaiapi.CallbackMsg) (orderStatus *model.OrderStatus) { if msg.Cmd == ebaiapi.CmdOrderPartRefund { partRefundData := msg.Data.(*ebaiapi.CBPartRefundInfo) orderStatus = &model.OrderStatus{ VendorOrderID: partRefundData.RefundID, // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 VendorID: model.VendorIDEBAI, OrderType: model.OrderTypeAfsOrder, RefVendorOrderID: utils.Int64ToStr(partRefundData.OrderID), RefVendorID: model.VendorIDEBAI, VendorStatus: utils.Int2Str(partRefundData.Status), Status: c.GetAfsStatusFromVendorStatus4PartRefund(partRefundData.Status), StatusTime: utils.Timestamp2Time(msg.Timestamp), Remark: buildFullReason(partRefundData.Reason, partRefundData.AdditionReason), } if orderStatus.Status == model.AfsOrderStatusWait4Approve && partRefundData.Type != ebaiapi.OrderPartRefuncTypeCustomer { orderStatus.Status = model.AfsOrderStatusNew } } else if msg.Cmd == ebaiapi.CmdOrderUserCancel { cancelData := msg.Data.(*ebaiapi.CBUserCancelInfo) orderStatus = &model.OrderStatus{ VendorOrderID: utils.Int64ToStr(cancelData.OrderID), // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 VendorID: model.VendorIDEBAI, OrderType: model.OrderTypeAfsOrder, RefVendorOrderID: utils.Int64ToStr(cancelData.OrderID), RefVendorID: model.VendorIDEBAI, VendorStatus: utils.Int2Str(cancelData.Type), Status: c.GetAfsStatusFromVendorStatus4UserCancel(cancelData.Type), StatusTime: utils.Timestamp2Time(msg.Timestamp), Remark: buildFullReason(cancelData.CancelReason, cancelData.AdditionReason), } } return orderStatus } // 审核售后单申请 func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) { if globals.EnableEbaiStoreWrite { if approveType == partner.AfsApproveTypeRefused { err = api.EbaiAPI.OrderDisagreeRefund(order.VendorOrderID, reason) } else { err = api.EbaiAPI.OrderAgreeRefund(order.VendorOrderID) } } return err } // 确认收到退货 func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { err = fmt.Errorf("内部错误,饿百平台不支持确认收到退货操作") return err } // 发起全款退款 func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { return c.PartRefundOrder(ctx, order, order.Skus, reason) } // 发起部分退款 func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) { if globals.EnableEbaiStoreWrite { err = api.EbaiAPI.OrderPartRefund(order.VendorOrderID, orderSkus2AfsSkus(refundSkuList)) } return err } func orderSkus2AfsSkus(refundSkuList []*model.OrderSku) (removeSkuList []*ebaiapi.RefundSku) { for _, v := range refundSkuList { refundSku := &ebaiapi.RefundSku{ CustomeSkuID: utils.Int2Str(v.SkuID), Number: utils.Int2Str(v.Count), } removeSkuList = append(removeSkuList, refundSku) } return removeSkuList } func (c *PurchaseHandler) GetOrderAfsInfo(ctx *jxcontext.Context, vendorOrderID, afsOrderID string) (orderAfsInfo *partner.OrderAfsInfo, err error) { orderAfsInfo = &partner.OrderAfsInfo{} if result, err := api.EbaiAPI.OrderPartRefundGet(vendorOrderID); err == nil { orderAfsInfo.VendorOrderID = vendorOrderID orderAfsInfo.AfsTotalShopMoney = utils.MustInterface2Int64(result["shop_fee"]) } return orderAfsInfo, err }