diff --git a/business/model/const.go b/business/model/const.go index 73b366fc1..42224e395 100644 --- a/business/model/const.go +++ b/business/model/const.go @@ -289,14 +289,15 @@ const ( OrderStatusCanceled = 115 // 订单已取消 OrderStatusEndEnd = 120 - AfsOrderStatusWait4Approve = 155 // 待审核售后单 - AfsOrderStatusCancelAfs = 156 // 用户取消售后 - AfsOrderStatusOnSaleAfs = 157 // 用户售中取消 - AfsOrderStatusNew = 160 // 已审核或不需要审核售后单 - AfsOrderStatusWait4ReceiveGoods = 165 // 退款退货的,需要商家确认收到货 - AfsOrderStatusReceivedGoods = 167 // 已确认收到货 - AfsOrderStatusFinished = 180 // 售后单成功完成 - AfsOrderStatusFailed = 190 // 售后单失败 + AfsOrderStatusWait4Approve = 155 // 待审核售后单 + AfsOrderStatusCancelAfs = 156 // 用户取消售后 + AfsOrderStatusOnSaleAfs = 157 // 用户售中取消 + AfsOrderStatusNew = 160 // 已审核或不需要审核售后单 + AfsOrderStatusWait4ReceiveGoods = 165 // 退款退货的,需要商家确认收到货 + AfsOrderStatusReceivedGoods = 167 // 已确认收到货 + AfsOrderStatusReceivedArbitration = 170 // 仲裁 + AfsOrderStatusFinished = 180 // 售后单成功完成 + AfsOrderStatusFailed = 190 // 售后单失败 ) const ( diff --git a/business/partner/purchase/ebai/callback.go b/business/partner/purchase/ebai/callback.go index 2b1fa423f..c581e6175 100644 --- a/business/partner/purchase/ebai/callback.go +++ b/business/partner/purchase/ebai/callback.go @@ -16,7 +16,7 @@ func OnCallbackMsg(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse if orderID := GetOrderIDFromMsg(msg); orderID != "" { jxutils.CallMsgHandler(func() { switch msg.Cmd { - case ebaiapi.CmdOrderCreate, ebaiapi.CmdOrderStatus, ebaiapi.CmdOrderUserCancel, ebaiapi.CmdOrderPartRefund: + case ebaiapi.CmdOrderCreate, ebaiapi.CmdOrderStatus, ebaiapi.CmdOrderUserCancel, ebaiapi.CmdOrderPartRefund, ebaiapi.CmdOrderReversePush: response = CurPurchaseHandler.onOrderMsg(msg) case ebaiapi.CmdOrderDeliveryStatus: response = CurPurchaseHandler.onWaybillMsg(msg) diff --git a/business/partner/purchase/ebai/financial.go b/business/partner/purchase/ebai/financial.go index 390d27310..56f52eacc 100644 --- a/business/partner/purchase/ebai/financial.go +++ b/business/partner/purchase/ebai/financial.go @@ -30,6 +30,17 @@ func (p *PurchaseHandler) onFinancialMsg(msg *ebaiapi.CallbackMsg) (response *eb err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(afsOrder) } } + } else if msg.Cmd == ebaiapi.CmdOrderReversePush { + if int(utils.MustInterface2Int64(msg.Body["refund_status"])) == ebaiapi.OrderPartRefundSuccess { + // 获取到部分退款订单id + afsOrderID := GetOrderIDFromMsg(msg) + // 处理部分退款信息 + orderData, err2 := api.EbaiAPI.OrderPartRefundGet(afsOrderID) + if err = err2; err == nil { + afsOrder := CurPurchaseHandler.AfsOrderDetail2Financial(orderData) + err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(afsOrder) + } + } } else if msg.Cmd == ebaiapi.CmdOrderUserCancel { // 全额退款处理 messageType := int(utils.MustInterface2Int64(msg.Body["type"])) if int(utils.MustInterface2Int64(msg.Body["cancel_type"])) == ebaiapi.OrderUserCancelTypeAfterSale && diff --git a/business/partner/purchase/ebai/order.go b/business/partner/purchase/ebai/order.go index b2a9aa1a7..b001c5c6c 100644 --- a/business/partner/purchase/ebai/order.go +++ b/business/partner/purchase/ebai/order.go @@ -643,6 +643,13 @@ func (c *PurchaseHandler) callbackMsg2Status(msg *ebaiapi.CallbackMsg) (orderSta if msgType == ebaiapi.OrderPartRefuncTypeMerchant && status == ebaiapi.OrderPartRefundSuccess { orderStatus.VendorStatus = fakeOrderAdjustFinished } + } else if msg.Cmd == ebaiapi.CmdOrderReversePush { + msgType := int(utils.MustInterface2Int64(msg.Body["operator_role"])) + status := int(utils.MustInterface2Int64(msg.Body["refund_status"])) + orderStatus.Remark = buildFullReason(utils.Interface2String(msg.Body["reason"]), utils.Interface2String(msg.Body["addition_reason"])) + if msgType == ebaiapi.OrderReverseRefuncTypeMerchant && status == ebaiapi.OrderReversePushApplySuccess { + orderStatus.VendorStatus = fakeOrderAdjustFinished + } } else if status, ok := msg.Body["status"]; ok { if vendorStatus, ok := status.(string); ok { orderStatus.VendorStatus = vendorStatus @@ -651,6 +658,7 @@ func (c *PurchaseHandler) callbackMsg2Status(msg *ebaiapi.CallbackMsg) (orderSta } orderStatus.Remark = utils.Interface2String(msg.Body["reason"]) } + if orderStatus.Status == 0 { orderStatus.Status = c.getStatusFromVendorStatus(orderStatus.VendorStatus) } diff --git a/business/partner/purchase/ebai/order_afs.go b/business/partner/purchase/ebai/order_afs.go index 2e5ac1cdf..5d738c3d1 100644 --- a/business/partner/purchase/ebai/order_afs.go +++ b/business/partner/purchase/ebai/order_afs.go @@ -25,6 +25,17 @@ var ( ebaiapi.OrderPartRefundFailed: model.AfsOrderStatusFailed, ebaiapi.OrderPartRefundMerchantRefused: model.AfsOrderStatusFailed, // 是否是中间状态 } + + AfsVendorStatus2Status4ReverseRefundMap = map[int]int{ + //ebaiapi.OrderReversePushApplyInit: model.AfsOrderStatusWait4Approve, // 初始化售后 + ebaiapi.OrderReversePushApply: model.AfsOrderStatusWait4Approve, // 申请售后 + ebaiapi.OrderReversePushApplyRefuse: model.AfsOrderStatusFailed, // 售后失败 + ebaiapi.OrderReversePushApplyArbitration: model.AfsOrderStatusReceivedArbitration, // 仲裁 + ebaiapi.OrderReversePushApplyClose: model.AfsOrderStatusFinished, // 售后结束 + ebaiapi.OrderReversePushApplySuccess: model.AfsOrderStatusFinished, // 售后成功 + ebaiapi.OrderReversePushApplyFail: model.AfsOrderStatusFailed, // 售后失败 + } + AfsVendorStatus2Status4UserCancel = map[int]int{ ebaiapi.OrderUserCancelApply: model.AfsOrderStatusWait4Approve, ebaiapi.OrderUserCancelCSIntervene: model.OrderStatusUnknown, @@ -44,8 +55,9 @@ func (c *PurchaseHandler) isAfsMsg(msg *ebaiapi.CallbackMsg) bool { case ebaiapi.CmdOrderUserCancel: // 1表示订单完成前用户全单取消申请流程, 2表示订单完成后用户全单退款申请流程 cancelType := int(utils.MustInterface2Int64(msg.Body["cancel_type"])) - return cancelType == ebaiapi.OrderUserCancelTypeAfterSale || cancelType == ebaiapi.OrderUserCancelTypeBeforeSale + case ebaiapi.CmdOrderReversePush: // 订单逆向消息推送 + return true } return false @@ -64,54 +76,15 @@ func (c *PurchaseHandler) onAfsOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaia 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) + globals.SugarLogger.Debug("====order.partrefund.push :- %s", utils.Format4Output(msg, false)) + afsOrder = c.makeAfsOrderInfoPartRefund(msg, orderStatus) + } else if msg.Cmd == ebaiapi.CmdOrderReversePush { + afsOrder, err = c.makeAfsOrderInfoReverseRefund(msg, orderStatus) + if err != nil { + return api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil) } } 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 @@ -127,37 +100,13 @@ func (c *PurchaseHandler) onAfsOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaia } } else { afsOrder2, err := partner.CurOrderManager.LoadAfsOrder(orderStatus.VendorOrderID, orderStatus.VendorID) - if 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 afsOrder2 == nil && err == nil && msg.Cmd == ebaiapi.CmdOrderPartRefund { + afsOrder := c.makeAfsOrderInfoPartRefund(msg, orderStatus) + if afsOrder != nil { + err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus) } + } else if afsOrder2 == nil && err == nil && msg.Cmd == ebaiapi.CmdOrderReversePush { + afsOrder, _ := c.makeAfsOrderInfoReverseRefund(msg, orderStatus) if afsOrder != nil { err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus) } @@ -168,7 +117,7 @@ func (c *PurchaseHandler) onAfsOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaia // 只有有售后订单就更新此订单的结算信息 var db = dao.GetDB() - if utils.Str2Int(orderStatus.VendorStatus) == ebaiapi.OrderPartRefundSuccess { + if (msg.Cmd == ebaiapi.CmdOrderPartRefund && utils.Str2Int(orderStatus.VendorStatus) == ebaiapi.OrderPartRefundSuccess) || (msg.Cmd == ebaiapi.CmdOrderReversePush && utils.Str2Int(orderStatus.VendorStatus) == ebaiapi.OrderReversePushApplySuccess) { orderData, err2 := api.EbaiAPI.OrderPartRefundGet(orderStatus.RefVendorOrderID) if err2 == nil && utils.MustInterface2Int64(orderData["merchant_income"]) != model.NO { goodsOrder, _ := partner.CurOrderManager.LoadOrder(orderStatus.RefVendorOrderID, model.VendorIDEBAI) @@ -202,16 +151,35 @@ func (c *PurchaseHandler) onAfsOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaia dao.UpdateEntity(dao.GetDB(), goodsOrder, "TotalShopMoney", "EarningPrice") } } - if utils.Str2Int(orderStatus.VendorStatus) == ebaiapi.OrderUserCancelMerchantAgreed { - afs, _ := partner.CurOrderManager.LoadAfsOrder(orderStatus.RefVendorOrderID, model.VendorIDEBAI) - if afs != nil { + + afs, _ := partner.CurOrderManager.LoadAfsOrder(orderStatus.RefVendorOrderID, model.VendorIDEBAI) + if msg.Cmd == ebaiapi.CmdOrderPartRefund { + switch utils.Str2Int(orderStatus.VendorStatus) { + case ebaiapi.OrderUserCancelMerchantAgreed, ebaiapi.OrderUserCancelCSAgreed: afs.Status = orderStatus.Status afs.VendorStatus = orderStatus.VendorStatus afs.Flag = model.YES - dao.UpdateEntity(dao.GetDB(), afs, "Status", "VendorStatus", "Flag") + case ebaiapi.OrderUserCancelCSRefused, ebaiapi.OrderUserCancelMerchantRefused, ebaiapi.OrderUserCancelInvalid: + afs.Status = orderStatus.Status + afs.VendorStatus = orderStatus.VendorStatus + afs.Flag = 3 + } + } else if msg.Cmd == ebaiapi.CmdOrderReversePush { + switch utils.Str2Int(orderStatus.VendorStatus) { + case ebaiapi.OrderReversePushApplySuccess: + afs.Status = orderStatus.Status + afs.VendorStatus = orderStatus.VendorStatus + afs.Flag = model.YES + case ebaiapi.OrderReversePushApplyRefuse, ebaiapi.OrderReversePushApplyFail: + afs.Status = orderStatus.Status + afs.VendorStatus = orderStatus.VendorStatus + afs.Flag = 3 } } + if afs != nil { + dao.UpdateEntity(db, afs, "Status", "VendorStatus", "Flag") + } retVal = api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil) } return retVal @@ -237,6 +205,10 @@ func (c *PurchaseHandler) GetAfsStatusFromVendorStatus4PartRefund(vendorStatus i return AfsVendorStatus2Status4PartRefundMap[vendorStatus] } +func (c *PurchaseHandler) GetAfsStatusFromVendorStatus4ReverseRefund(vendorStatus int) int { + return AfsVendorStatus2Status4ReverseRefundMap[vendorStatus] +} + func (c *PurchaseHandler) GetAfsStatusFromVendorStatus4UserCancel(vendorStatus int) int { return AfsVendorStatus2Status4UserCancel[vendorStatus] } @@ -258,6 +230,19 @@ func (c *PurchaseHandler) callbackAfsMsg2Status(msg *ebaiapi.CallbackMsg) (order if orderStatus.Status == model.AfsOrderStatusWait4Approve && partRefundData.Type != ebaiapi.OrderPartRefuncTypeCustomer { orderStatus.Status = model.AfsOrderStatusNew } + } else if msg.Cmd == ebaiapi.CmdOrderReversePush { + partRefundData := msg.Data.(*ebaiapi.CBOrderReversePush) + orderStatus = &model.OrderStatus{ + VendorOrderID: utils.Int64ToStr(partRefundData.RefundOrderId), // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 + VendorID: model.VendorIDEBAI, + OrderType: model.OrderTypeAfsOrder, + RefVendorOrderID: partRefundData.OrderId, + RefVendorID: model.VendorIDEBAI, + VendorStatus: utils.Int2Str(partRefundData.CurReverseEvent.RefundStatus), + Status: c.GetAfsStatusFromVendorStatus4ReverseRefund(partRefundData.CurReverseEvent.RefundStatus), + StatusTime: utils.Timestamp2Time(msg.Timestamp), + Remark: partRefundData.CurReverseEvent.RefundReasonDesc, + } } else if msg.Cmd == ebaiapi.CmdOrderUserCancel { cancelData := msg.Data.(*ebaiapi.CBUserCancelInfo) orderStatus = &model.OrderStatus{ diff --git a/business/partner/purchase/ebai/order_afs_ex.go b/business/partner/purchase/ebai/order_afs_ex.go new file mode 100644 index 000000000..184caa8dc --- /dev/null +++ b/business/partner/purchase/ebai/order_afs_ex.go @@ -0,0 +1,89 @@ +package ebai + +import ( + "encoding/json" + "git.rosy.net.cn/baseapi/platformapi/ebaiapi" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/globals/api" + "strings" +) + +func (c *PurchaseHandler) makeAfsOrderInfoPartRefund(msg *ebaiapi.CallbackMsg, orderStatus *model.OrderStatus) *model.AfsOrder { + var afsOrder *model.AfsOrder + 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) + } + return afsOrder +} + +func (c *PurchaseHandler) makeAfsOrderInfoReverseRefund(msg *ebaiapi.CallbackMsg, orderStatus *model.OrderStatus) (*model.AfsOrder, error) { + var afsOrder *model.AfsOrder + partRefundData := msg.Data.(*ebaiapi.CBOrderReversePush) + afsOrder = &model.AfsOrder{ + VendorID: model.VendorIDEBAI, + AfsOrderID: orderStatus.VendorOrderID, + VendorOrderID: orderStatus.RefVendorOrderID, + VendorStoreID: utils.Int2Str(partRefundData.PlatformShopId), + StoreID: 0, + AfsCreatedAt: utils.Timestamp2Time(msg.Timestamp), + VendorAppealType: "", + AppealType: model.AfsAppealTypeRefund, + VendorReasonType: utils.Int2Str(partRefundData.CurReverseEvent.ReasonCode), + ReasonType: c.convertAfsReasonType(utils.Int2Str(partRefundData.CurReverseEvent.ReasonCode)), + ReasonDesc: utils.LimitUTF8StringLen(partRefundData.CurReverseEvent.RefundReasonDesc, 1024), + ReasonImgList: utils.LimitUTF8StringLen(strings.Join(partRefundData.CurReverseEvent.ImageList, ","), 1024), + RefundType: model.AfsTypePartRefund, + VendorOrgCode: msg.Source, + } + // 查询售后列表 + refundSku, _, err := api.EbaiAPI.GetReverseOrder(orderStatus.RefVendorOrderID) + if err == nil { + refundSkuList := make([]*ebaiapi.ReverseSkuList, 0, len(refundSku)) + refundByte, _ := json.Marshal(refundSku) + if err = json.Unmarshal(refundByte, &refundSkuList); err != nil { + return nil, err + } + for _, sku := range refundSkuList { + orderSku := &model.OrderSkuFinancial{ + Count: sku.RefundQuantity, + VendorSkuID: utils.Int64ToStr(sku.PlatformSkuId), + SkuID: utils.Str2Int(sku.CustomSkuId), + Name: sku.SkuName, + UserMoney: int64(sku.RefundUserAmount), + PmSkuSubsidyMoney: int64(sku.DiscountDetail.PlatformDiscountAmount), + } + afsOrder.SkuUserMoney += orderSku.UserMoney + afsOrder.PmSubsidyMoney += orderSku.PmSubsidyMoney + afsOrder.Skus = append(afsOrder.Skus, orderSku) + } + } + return afsOrder, nil +}