Files
jx-callback/business/partner/purchase/ebai/order_afs.go
suyl 5b1e37ffd7 aa
2021-06-18 16:11:39 +08:00

273 lines
12 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 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
}