添加淘鲜达

This commit is contained in:
邹宗楠
2023-06-28 10:04:08 +08:00
parent 64e4339aeb
commit c0a97b4fad
51 changed files with 2109 additions and 2007 deletions

View File

@@ -1,13 +1,12 @@
package mtwm
package tao_vegetable
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/platformapi/tao_vegetable"
request3156 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability3156/request"
domain591 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability591/domain"
request591 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability591/request"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
@@ -15,57 +14,39 @@ import (
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
)
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,
tao_vegetable.OrderStatusApplyAfs: model.AfsOrderStatusWait4Approve,
tao_vegetable.OrderStatusCancelAfs: model.AfsOrderStatusCancelAfs,
tao_vegetable.OrderStatusRefundSuccess: model.AfsOrderStatusFinished,
}
)
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)
func (c *PurchaseHandler) isAfsMsg(orderStatus string, orderId string) bool {
if orderStatus == tao_vegetable.OrderStatusApplyAfs || orderStatus == tao_vegetable.OrderStatusCancelAfs || orderStatus == tao_vegetable.OrderStatusRefundSuccess {
order, _ := partner.CurOrderManager.LoadOrder(orderId, model.VendorIDTaoVegetable)
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 true
}
}
return false
}
func (c *PurchaseHandler) OnAfsOrderMsg(msg *mtwmapi.CallbackMsg) (retVal *mtwmapi.CallbackResponse) {
func (c *PurchaseHandler) OnAfsOrderMsg(orderId, status string, msg interface{}) (retVal *tao_vegetable.CallBackResult) {
jxutils.CallMsgHandlerAsync(func() {
retVal = c.onAfsOrderMsg(msg)
}, jxutils.ComposeUniversalOrderID(GetOrderIDFromMsg(msg), model.VendorIDMTWM))
retVal = c.onAfsOrderMsg(status, msg)
}, jxutils.ComposeUniversalOrderID(orderId, model.VendorIDTaoVegetable))
return retVal
}
// todo 对于退款与部分退款order.go与这个文件中对于状态的处理不一致
func (c *PurchaseHandler) onAfsOrderMsg(msg *mtwmapi.CallbackMsg) (retVal *mtwmapi.CallbackResponse) {
// todo 淘宝暂无部分退款,只有整单退款
func (c *PurchaseHandler) onAfsOrderMsg(status string, msg interface{}) (retVal *tao_vegetable.CallBackResult) {
var err error
orderStatus := c.callbackAfsMsg2Status(msg)
var db = dao.GetDB()
orderStatus := c.callbackAfsMsg2Status(status, msg)
needCallNew := orderStatus.Status == model.AfsOrderStatusWait4Approve || orderStatus.Status == model.AfsOrderStatusNew
if !needCallNew {
_, err := partner.CurOrderManager.LoadAfsOrder(orderStatus.VendorOrderID, orderStatus.VendorID)
@@ -73,73 +54,80 @@ func (c *PurchaseHandler) onAfsOrderMsg(msg *mtwmapi.CallbackMsg) (retVal *mtwma
if dao.IsNoRowsError(err) {
needCallNew = true
} else {
return mtwmapi.Err2CallbackResponse(err, "")
return tao_vegetable.CallBackResultInfo(err)
}
}
}
if needCallNew {
refundData := msg.(*tao_vegetable.UserApplyRefundCallBack)
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,
afsOrder = &model.AfsOrder{
VendorID: model.VendorIDTaoVegetable,
AfsOrderID: orderStatus.VendorOrderID,
VendorOrderID: orderStatus.RefVendorOrderID,
VendorStoreID: refundData.StoreId,
StoreID: 0,
AfsCreatedAt: orderStatus.StatusTime,
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,
VendorAppealType: status, // 原始售后方式
AppealType: model.AfsAppealTypeUserCancel, // 淘宝这个接口下发的只有用户取消
VendorReasonType: refundData.RefundReason,
ReasonType: 0,
ReasonDesc: refundData.RefundReason,
ReasonImgList: utils.LimitUTF8StringLen(refundData.RefundPictures, 1024),
RefundType: model.AfsTypeFullRefund,
VendorOrgCode: refundData.MerchantCode,
}
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
}
refundIds := make([]int64, 0, 0)
bizOrderIds := make([]int64, len(refundData.SubRefundOrders))
for _, v := range refundData.SubRefundOrders {
bizOrderIds = append(bizOrderIds, utils.Str2Int64(v.OutSubOrderId))
}
refundIds = append(refundIds, utils.Str2Int64(refundData.BizRefundId))
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)
taoAfsOrderDetail, err := getAPI(refundData.MerchantCode, 0, "").QueryAfsOrderDetail(&request591.AlibabaWdkOrderRefundGetRequest{
BizOrderIds: &bizOrderIds,
RefundIds: &refundIds,
OrderFrom: nil,
ShopId: nil,
StoreId: &refundData.StoreId,
})
if err != nil {
return tao_vegetable.CallBackResultInfo(err)
}
taoAfsOrder := *taoAfsOrderDetail.Orders
afsOrder.FreightUserMoney = *taoAfsOrder[0].RefundPostFee
afsOrder.AfsFreightMoney = *taoAfsOrder[0].RefundPostFee // 暂时未发现退货取件费用
afsOrder.BoxMoney = 0 // 餐盒费
afsOrder.TongchengFreightMoney = 0 // 同城配送费
afsOrder.SkuBoxMoney = 0 // 商品包装费
afsOrder.VendorStatus = orderStatus.VendorStatus // 退货状态
// 订单商品详细信息
skuList, err := getAPI(refundData.MerchantCode, 0, "").QueryOrderDetail(&request591.AlibabaAelophyOrderGetRequest{OrderGetRequest: &domain591.AlibabaAelophyOrderGetOrderGetRequest{
StoreId: utils.String2Pointer(refundData.StoreId),
BizOrderId: utils.Int64ToPointer(utils.Str2Int64(refundData.OutOrderId)),
}})
if err != nil {
return tao_vegetable.CallBackResultInfo(err)
}
for _, sku := range *skuList.SubOrderResponseList {
orderSku := &model.OrderSkuFinancial{
Count: utils.Str2Int(*sku.BuySaleQuantity),
VendorSkuID: *sku.SkuCode,
SkuID: utils.Str2Int(*sku.SkuCode),
Name: *sku.SkuName,
UserMoney: *sku.OriginalFee - *sku.DiscountFee,
PmSkuSubsidyMoney: *sku.DiscountPlatformFee, // 平台补贴商品
}
afsOrder.PmSkuSubsidyMoney += orderSku.PmSkuSubsidyMoney
afsOrder.SkuUserMoney += orderSku.UserMoney
afsOrder.Skus = append(afsOrder.Skus, orderSku)
}
if afsOrder != nil {
//直接就来一个新的售后单,并且还是售后完成的
@@ -149,70 +137,132 @@ func (c *PurchaseHandler) onAfsOrderMsg(msg *mtwmapi.CallbackMsg) (retVal *mtwma
err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus)
}
} else {
// 用户取消售后
if status == tao_vegetable.OrderStatusCancelAfs {
// 删除售后单
afsOrder, err := dao.GetAfsOrders(db, model.VendorIDTaoVegetable, orderStatus.RefVendorOrderID, orderStatus.VendorOrderID)
if err != nil || afsOrder == nil {
globals.SugarLogger.Debugf("用户取消售后单,获取之前生成的售后单失败")
return tao_vegetable.CallBackResultInfo(err)
}
if err = utils.CallFuncLogError(func() error {
_, err = dao.DeleteEntity(db, afsOrder[0], "VendorOrderID", "VendorID")
return err
}, "SaveAfsOrder delete AfsOrder, afsOrderID:%s", afsOrder[0].AfsOrderID); err != nil {
return tao_vegetable.CallBackResultInfo(err)
}
// 删除售后商品
if err = utils.CallFuncLogError(func() error {
_, err = dao.DeleteEntity(db, &model.OrderSkuFinancial{
VendorOrderID: afsOrder[0].VendorOrderID,
VendorID: afsOrder[0].VendorID,
IsAfsOrder: 1,
}, "VendorOrderID", "VendorID", "IsAfsOrder")
return err
}, "SaveAfsOrder delete OrderSkuFinancial, afsOrderID:%s", afsOrder[0].AfsOrderID); err != nil {
return tao_vegetable.CallBackResultInfo(err)
}
// 订单更改为待配送
goodsOrder, _ := partner.CurOrderManager.LoadOrder(orderStatus.RefVendorOrderID, model.VendorIDTaoVegetable)
goodsOrder.Status = model.OrderStatusFinishedPickup
goodsOrder.VendorStatus = status
dao.UpdateEntity(db, goodsOrder, "Status", "VendorStatus")
}
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")
if err == nil && status == tao_vegetable.OrderStatusRefundSuccess {
goodsOrder, _ := partner.CurOrderManager.LoadOrder(orderStatus.RefVendorOrderID, orderStatus.VendorID)
goodsOrder.Status = model.OrderStatusCanceled
goodsOrder.VendorStatus = orderStatus.VendorStatus
dao.UpdateEntity(db, goodsOrder, "Status", "VendorStatus")
}
}
}
return mtwmapi.Err2CallbackResponse(err, "")
return tao_vegetable.CallBackResultInfo(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)
func (c *PurchaseHandler) callbackAfsMsg2Status(status string, msg interface{}) (orderStatus *model.OrderStatus) {
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,
VendorID: model.VendorIDTaoVegetable,
OrderType: model.OrderTypeAfsOrder,
RefVendorID: model.VendorIDTaoVegetable,
}
if refundData.RefundID > 0 {
orderStatus.VendorOrderID = utils.Int64ToStr(refundData.RefundID)
} else {
switch status {
case tao_vegetable.OrderStatusApplyAfs:
refundData := msg.(*tao_vegetable.UserApplyRefundCallBack)
orderStatus.RefVendorOrderID = refundData.OutOrderId
orderStatus.VendorStatus = fmt.Sprintf("%s:%s", tao_vegetable.OrderStatusApplyAfs, "用户申请取消")
orderStatus.Status = c.GetAfsStatusFromVendorStatus(tao_vegetable.OrderStatusApplyAfs)
orderStatus.StatusTime = utils.Str2Time(refundData.Timestamp)
orderStatus.Remark = refundData.Remarks
orderStatus.VendorOrderID = refundData.BizRefundId
case tao_vegetable.OrderStatusCancelAfs:
refundData := msg.(*tao_vegetable.UserCancelRefundApply)
orderStatus.RefVendorOrderID = refundData.OutOrderId
orderStatus.VendorStatus = fmt.Sprintf("%s:%s", tao_vegetable.OrderStatusCancelAfs, "用户取消售后申请")
orderStatus.Status = c.GetAfsStatusFromVendorStatus(tao_vegetable.OrderStatusCancelAfs)
orderStatus.StatusTime = utils.Str2Time(refundData.Timestamp)
orderStatus.VendorOrderID = refundData.BizRefundId
//case tao_vegetable.OrderStatusOnSaleCancel:
// refundData := msg.(*tao_vegetable.OnSaleCancel)
// orderStatus.RefVendorOrderID = utils.Int64ToStr(refundData.BizOrderId)
// orderStatus.VendorStatus = fmt.Sprintf("%s:%s", tao_vegetable.OrderStatusOnSaleCancel, "用户售中取消")
// orderStatus.Status = c.GetAfsStatusFromVendorStatus(tao_vegetable.OrderStatusOnSaleCancel)
// orderStatus.StatusTime = utils.Str2Time(refundData.Timestamp)
// orderStatus.VendorOrderID = refundData.IdempotentId
case tao_vegetable.OrderStatusRefundSuccess:
refundData := msg.(*tao_vegetable.RefundOrderFinish)
orderStatus.RefVendorOrderID = refundData.OutMainRefundId
orderStatus.VendorStatus = fmt.Sprintf("%s:%s", tao_vegetable.OrderStatusRefundSuccess, "用户售后退款成功")
orderStatus.Status = c.GetAfsStatusFromVendorStatus(tao_vegetable.OrderStatusRefundSuccess)
orderStatus.StatusTime = utils.Str2Time(refundData.Timestamp)
orderStatus.VendorOrderID = refundData.BizSubRefundId
}
if orderStatus.VendorOrderID == "" {
orderStatus.VendorOrderID = orderStatus.RefVendorOrderID
}
return orderStatus
}
func (c *PurchaseHandler) GetAfsStatusFromVendorStatus(resType int, notifyType string) int {
func (c *PurchaseHandler) GetAfsStatusFromVendorStatus(notifyType string) int {
status := AfsVendorStatus2StatusMap[notifyType]
if status == model.AfsOrderStatusWait4Approve && resType != mtwmapi.ResTypePending {
status = model.AfsOrderStatusNew
}
//if status == model.AfsOrderStatusWait4Approve || status == model.AfsOrderStatusOnSaleAfs {
// 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)
if approveType == partner.AfsApproveTypeRefused {
param := &request3156.AlibabaTclsAelophyRefundAgreeRequest{
StoreId: utils.String2Pointer(order.VendorStoreID),
OutOrderId: utils.String2Pointer(order.VendorOrderID),
OrderFrom: utils.Int64ToPointer(utils.Str2Int64(tao_vegetable.TaoVegetableChannelCode)),
}
param.AuditMemo = utils.String2Pointer(fmt.Sprintf("商户同意退款"))
if reason != "" {
param.AuditMemo = utils.String2Pointer(*param.AuditMemo + fmt.Sprintf(",%s", reason))
}
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromAfsOrder(order), order.VendorStoreID).AgreeUserCancel(param)
} else if approveType == partner.AfsApproveTypeRefusedToRefundMoney {
return errors.New("此平台暂时不支持")
} else {
param := &request3156.AlibabaTclsAelophyRefundDisagreeRequest{
RefundId: utils.String2Pointer(order.AfsOrderID),
RejectReason: utils.String2Pointer(reason),
OrderFrom: utils.Int64ToPointer(utils.Str2Int64(tao_vegetable.TaoVegetableChannelCode)),
}
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromAfsOrder(order), order.VendorStoreID).DisAgreeUserCancel(param)
if err != nil {
order.Status = model.AfsOrderStatusFailed
order.VendorStatus = "老板拒绝"
order.ReasonDesc += reason + ","
dao.UpdateEntity(dao.GetDB(), order, "Status", "ReasonDesc", "VendorStatus")
}
}
return err