This commit is contained in:
邹宗楠
2023-06-15 11:22:37 +08:00
parent 448525cd91
commit 6cacb74ecc
16 changed files with 3730 additions and 0 deletions

View File

@@ -0,0 +1,251 @@
package mtwm
import (
"errors"
"fmt"
"git.rosy.net.cn/jx-callback/globals/api"
"net/url"
"strings"
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
"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/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
)
var (
// AfsVendorStatus2StatusMap = map[int]int{
// mtwmapi.ResTypePending: model.AfsOrderStatusWait4Approve,
// mtwmapi.ResTypeMerchantRefused: model.AfsOrderStatusFailed,
// mtwmapi.ResTypeMerchantAgreed: model.AfsOrderStatusFinished,
// mtwmapi.ResTypeCSRefused: model.AfsOrderStatusFailed,
// mtwmapi.ResTypeCSAgreed: model.AfsOrderStatusFinished,
// mtwmapi.ResTypeTimeoutAutoAgreed: model.AfsOrderStatusFinished,
// mtwmapi.ResTypeAutoAgreed: model.AfsOrderStatusFinished,
// mtwmapi.ResTypeUserCancelApply: model.AfsOrderStatusFailed,
// mtwmapi.ResTypeUserCancelComplain: model.AfsOrderStatusFailed,
// }
AfsVendorStatus2StatusMap = map[string]int{
mtwmapi.NotifyTypeApply: model.AfsOrderStatusWait4Approve,
mtwmapi.NotifyTypePartyApply: model.AfsOrderStatusWait4Approve,
mtwmapi.NotifyTypeSuccess: model.AfsOrderStatusFinished,
mtwmapi.NotifyTypeReject: model.AfsOrderStatusFailed,
mtwmapi.NotifyTypeCancelRefund: model.AfsOrderStatusFailed,
mtwmapi.NotifyTypeCancelRefundComplaint: model.AfsOrderStatusFailed,
}
)
func (c *PurchaseHandler) isAfsMsg(msg *mtwmapi.CallbackMsg) bool {
if msg.Cmd == mtwmapi.MsgTypeOrderRefund || msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund {
// refundData := msg.Data.(*mtwmapi.CallbackRefundInfo)
orderID := utils.Str2Int64(GetOrderIDFromMsg(msg))
order, _ := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(orderID), model.VendorIDMTWM)
if order != nil {
//status, err := getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), order.VendorStoreID).OrderViewStatus(orderID)
//if err == nil {
//return utils.Int2Str(status) == mtwmapi.OrderStatusFinished
return true //TODO 有的美团订单售前退款,也当做售后处理试试
//}
}
}
return false
}
func (c *PurchaseHandler) OnAfsOrderMsg(msg *mtwmapi.CallbackMsg) (retVal *mtwmapi.CallbackResponse) {
jxutils.CallMsgHandlerAsync(func() {
retVal = c.onAfsOrderMsg(msg)
}, jxutils.ComposeUniversalOrderID(GetOrderIDFromMsg(msg), model.VendorIDMTWM))
return retVal
}
// todo 对于退款与部分退款order.go与这个文件中对于状态的处理不一致
func (c *PurchaseHandler) onAfsOrderMsg(msg *mtwmapi.CallbackMsg) (retVal *mtwmapi.CallbackResponse) {
var err error
orderStatus := c.callbackAfsMsg2Status(msg)
needCallNew := orderStatus.Status == model.AfsOrderStatusWait4Approve || orderStatus.Status == model.AfsOrderStatusNew
if !needCallNew {
_, err := partner.CurOrderManager.LoadAfsOrder(orderStatus.VendorOrderID, orderStatus.VendorID)
if err != nil {
if dao.IsNoRowsError(err) {
needCallNew = true
} else {
return mtwmapi.Err2CallbackResponse(err, "")
}
}
}
if needCallNew {
var afsOrder *model.AfsOrder
refundData := msg.Data.(*mtwmapi.CallbackRefundInfo)
if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund {
afsOrder = &model.AfsOrder{
VendorID: model.VendorIDMTWM,
AfsOrderID: orderStatus.VendorOrderID,
VendorOrderID: orderStatus.RefVendorOrderID,
VendorStoreID: "",
StoreID: 0,
AfsCreatedAt: utils.Timestamp2Time(refundData.Timestamp),
VendorAppealType: "",
AppealType: model.AfsAppealTypeRefund,
VendorReasonType: "",
ReasonType: model.AfsReasonNotOthers,
ReasonDesc: utils.LimitUTF8StringLen(refundData.Reason, 1024),
ReasonImgList: utils.LimitUTF8StringLen(strings.Join(refundData.PictureList, ","), 1024),
RefundType: model.AfsTypePartRefund,
VendorOrgCode: msg.AppID,
// FreightUserMoney: afsInfo.OrderFreightMoney,
// AfsFreightMoney: afsInfo.AfsFreight,
// BoxMoney: afsInfo.PackagingMoney,
// TongchengFreightMoney: afsInfo.TongchengFreightMoney,
// SkuBoxMoney: afsInfo.MealBoxMoney,
}
for _, sku := range refundData.FoodList {
orderSku := &model.OrderSkuFinancial{
// VendorID: model.VendorIDMTWM,
AfsOrderID: afsOrder.AfsOrderID,
// VendorOrderID: afsOrder.VendorOrderID,
// VendorStoreID: afsOrder.VendorStoreID,
// StoreID: afsOrder.StoreID,
IsAfsOrder: 1,
Count: sku.Count,
// ConfirmTime: afsOrder.AfsCreateAt,
VendorSkuID: sku.SkuID,
SkuID: int(utils.Str2Int64WithDefault(sku.SkuID, 0)),
Name: sku.FoodName,
UserMoney: jxutils.StandardPrice2Int(sku.RefundPrice)*int64(sku.Count) + jxutils.StandardPrice2Int(sku.BoxPrice)*int64(sku.BoxNum),
}
if orderSku.VendorSkuID == "" || orderSku.VendorSkuID == "0" {
orderSku.VendorSkuID = sku.AppFoodCode
}
afsOrder.SkuUserMoney += orderSku.UserMoney
afsOrder.Skus = append(afsOrder.Skus, orderSku)
}
//afsOrder.PmSubsidyMoney += afsOrder.RefundMoney - afsOrder.SkuUserMoney
} else {
if afsOrder = c.createAfsOrder(msg.FormData); afsOrder != nil {
// if orderFinancial, err2 := partner.CurOrderManager.LoadOrderFinancial(orderStatus.RefVendorOrderID, model.VendorIDMTWM); err2 == nil {
// afsOrder = c.OrderFinancialDetail2Refund(orderFinancial, msg.FormData)
afsOrder.AfsOrderID = orderStatus.VendorOrderID
afsOrder.RefundType = model.AfsTypeFullRefund
afsOrder.AppealType = model.AfsAppealTypeRefund
afsOrder.VendorReasonType = ""
afsOrder.ReasonType = model.AfsReasonNotOthers
afsOrder.ReasonDesc = utils.LimitUTF8StringLen(refundData.Reason, 1024)
afsOrder.ReasonImgList = utils.LimitUTF8StringLen(strings.Join(refundData.PictureList, ","), 1024)
}
}
if afsOrder != nil {
//直接就来一个新的售后单,并且还是售后完成的
if orderStatus.Status == model.AfsOrderStatusFinished {
afsOrder.AfsFinishedAt = afsOrder.AfsCreatedAt
}
err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus)
}
} else {
if err := partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus); err == nil {
// 订单回调全额退款接口时,将订单状态修改为取消
refundData := msg.Data.(*mtwmapi.CallbackRefundInfo)
if refundData.NotifyType == "agree" && msg.Cmd == mtwmapi.MsgTypeOrderRefund {
order, _ := partner.CurOrderManager.LoadOrder(orderStatus.RefVendorOrderID, model.VendorIDMTWM)
order.Status = model.OrderStatusCanceled
dao.UpdateEntity(dao.GetDB(), order, "Status")
}
}
}
return mtwmapi.Err2CallbackResponse(err, "")
}
func (p *PurchaseHandler) createAfsOrder(orderData url.Values) (afsOrder *model.AfsOrder) {
afsOrder, err := partner.CurOrderManager.CreateAfsOrderFromOrder(orderData.Get("order_id"), model.VendorIDMTWM)
if err == nil {
afsOrder.AfsOrderID = orderData.Get("refund_id")
afsOrder.AfsCreatedAt = utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp")))
if afsOrder.AfsOrderID == "" {
afsOrder.AfsOrderID = afsOrder.VendorOrderID
}
} else {
afsOrder = nil
}
return afsOrder
}
func (c *PurchaseHandler) callbackAfsMsg2Status(msg *mtwmapi.CallbackMsg) (orderStatus *model.OrderStatus) {
refundData := msg.Data.(*mtwmapi.CallbackRefundInfo)
orderStatus = &model.OrderStatus{
VendorID: model.VendorIDMTWM,
OrderType: model.OrderTypeAfsOrder,
RefVendorOrderID: utils.Int64ToStr(refundData.OrderID),
RefVendorID: model.VendorIDMTWM,
VendorStatus: fmt.Sprintf("%s:%d", refundData.NotifyType, refundData.ResType),
Status: c.GetAfsStatusFromVendorStatus(refundData.ResType, refundData.NotifyType),
StatusTime: utils.Timestamp2Time(refundData.Timestamp),
Remark: refundData.Reason,
}
if refundData.RefundID > 0 {
orderStatus.VendorOrderID = utils.Int64ToStr(refundData.RefundID)
} else {
orderStatus.VendorOrderID = orderStatus.RefVendorOrderID
}
return orderStatus
}
func (c *PurchaseHandler) GetAfsStatusFromVendorStatus(resType int, notifyType string) int {
status := AfsVendorStatus2StatusMap[notifyType]
if status == model.AfsOrderStatusWait4Approve && resType != mtwmapi.ResTypePending {
status = model.AfsOrderStatusNew
}
return status
}
// 审核售后单申请
func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) {
if globals.EnableMtwmStoreWrite {
if approveType == partner.AfsApproveTypeRefused {
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromAfsOrder(order), order.VendorStoreID).OrderRefundReject(utils.Str2Int64(order.VendorOrderID), reason)
} else if approveType == partner.AfsApproveTypeRefusedToRefundMoney {
return errors.New("此平台暂时不支持")
} else {
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromAfsOrder(order), order.VendorStoreID).OrderRefundAgree(utils.Str2Int64(order.VendorOrderID), reason)
}
}
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 fmt.Errorf("%s不支持售后全额退款请让买家发起退款", model.VendorChineseNames[model.VendorIDMTWM])
}
// 发起部分退款
func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) {
return c.AdjustOrder(ctx, order, refundSkuList, reason)
}
func (c *PurchaseHandler) GetOrderAfsInfo(ctx *jxcontext.Context, vendorOrderID, afsOrderID string) (orderAfsInfo *partner.OrderAfsInfo, err error) {
orderAfsInfo = &partner.OrderAfsInfo{}
var afsTotalShopMoney int64
if list, err := api.MtwmAPI.GetOrderRefundDetail(utils.Str2Int64(vendorOrderID), 0); err == nil {
for _, v := range list {
if v.RefundPartialEstimateCharge.SettleAmount != "" {
afsTotalShopMoney += jxutils.StandardPrice2Int(utils.Str2Float64(v.RefundPartialEstimateCharge.SettleAmount))
}
}
}
if order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDMTWM); err == nil {
orderAfsInfo.AfsTotalShopMoney = order.TotalShopMoney + afsTotalShopMoney
}
return orderAfsInfo, err
}