Files
jx-callback/business/partner/purchase/tao_vegetable/order_afs.go
邹宗楠 1d1f547c72 1
2023-07-05 15:46:58 +08:00

375 lines
16 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 tao_vegetable
import (
"errors"
"fmt"
"git.rosy.net.cn/baseapi/platformapi/tao_vegetable"
domain3156 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability3156/domain"
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"
"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"
"git.rosy.net.cn/jx-callback/globals/api"
"time"
)
var (
AfsVendorStatus2StatusMap = map[string]int{
tao_vegetable.OrderStatusApplyAfs: model.AfsOrderStatusWait4Approve,
tao_vegetable.OrderStatusCancelAfs: model.AfsOrderStatusCancelAfs,
tao_vegetable.OrderStatusRefundSuccess: model.AfsOrderStatusFinished,
}
)
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)
order, _ := partner.CurOrderManager.LoadOrder2(orderId, model.VendorIDTaoVegetable)
if order != nil {
return true
}
}
return false
}
func (c *PurchaseHandler) OnAfsOrderMsg(orderId, status string, msg interface{}) (retVal *tao_vegetable.CallBackResult) {
// 取消线程池执行代码,异步返回
//jxutils.CallMsgHandlerAsync(func() {
retVal = c.onAfsOrderMsg(status, msg)
//}, jxutils.ComposeUniversalOrderID(orderId, model.VendorIDTaoVegetable))
return retVal
}
// todo 淘宝暂无部分退款,只有整单退款
func (c *PurchaseHandler) onAfsOrderMsg(status string, msg interface{}) (retVal *tao_vegetable.CallBackResult) {
var err error
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)
if err != nil {
if dao.IsNoRowsError(err) {
needCallNew = true
} else {
return tao_vegetable.CallBackResultInfo(err)
}
}
}
if needCallNew {
refundData := msg.(*tao_vegetable.UserApplyRefundCallBack)
var afsOrder *model.AfsOrder
var api = getAPI("", 0, refundData.StoreId)
afsOrder = &model.AfsOrder{
VendorID: model.VendorIDTaoVegetable,
AfsOrderID: orderStatus.VendorOrderID,
VendorOrderID: orderStatus.RefVendorOrderID,
VendorStoreID: refundData.StoreId,
StoreID: 0,
AfsCreatedAt: orderStatus.StatusTime,
VendorAppealType: status, // 原始售后方式
AppealType: model.AfsAppealTypeUserCancel, // 淘宝这个接口下发的只有用户取消
VendorReasonType: refundData.RefundReason,
ReasonType: 0,
ReasonDesc: refundData.RefundReason,
ReasonImgList: utils.LimitUTF8StringLen(refundData.RefundPictures, 1024),
VendorOrgCode: api.GetVendorOrgCode(),
}
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))
//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 = 0 // 订单运费
afsOrder.AfsFreightMoney = 0 // 暂时未发现退货取件费用
afsOrder.BoxMoney = 0 // 餐盒费
afsOrder.TongchengFreightMoney = 0 // 同城配送费
afsOrder.SkuBoxMoney = 0 // 商品包装费
afsOrder.VendorStatus = orderStatus.VendorStatus // 退货状态
// 订单商品详细信息
queryOrderDetailParam := &request591.AlibabaAelophyOrderGetRequest{OrderGetRequest: &domain591.AlibabaAelophyOrderGetOrderGetRequest{
StoreId: utils.String2Pointer(refundData.StoreId),
}}
order, err := partner.CurOrderManager.LoadOrder2(refundData.OutOrderId, model.VendorIDTaoVegetable)
if err != nil {
globals.SugarLogger.Debugf("用户申请售后时,通过售后外部渠道订单号获取主订单失败:%s", err.Error())
return tao_vegetable.CallBackResultInfo(err)
}
if order == nil {
globals.SugarLogger.Debugf("数据库订单查询失败,订单号异常 :%s", refundData.OutOrderId)
return tao_vegetable.CallBackResultInfo(errors.New("订单号异常"))
}
queryOrderDetailParam.OrderGetRequest.BizOrderId = utils.Int64ToPointer(utils.Str2Int64(order.VendorOrderID))
skuList, err := api.QueryOrderDetail(queryOrderDetailParam)
if err != nil {
return tao_vegetable.CallBackResultInfo(err)
}
var refundSkuCount int64 = 0
var orderSkuCount int64 = 0
for _, refundSku := range refundData.SubRefundOrders {
refundSkuCount += refundSku.RefundAmount
for _, sku := range *skuList.SubOrderResponseList {
if refundSku.OutSubOrderId == *sku.OutSubOrderId {
orderSku := &model.OrderSkuFinancial{
Count: utils.Float64TwoInt(*sku.BuySaleQuantity),
VendorSkuID: *sku.SkuCode,
SkuID: utils.Str2Int(*sku.SkuCode),
Name: *sku.SkuName,
UserMoney: *sku.OriginalFee - *sku.DiscountFee,
PmSkuSubsidyMoney: *sku.DiscountPlatformFee, // 平台补贴商品
VendorOrderID: orderStatus.VendorOrderID,
VendorSubOrderID: *sku.OutSubOrderId,
}
afsOrder.PmSkuSubsidyMoney += orderSku.PmSkuSubsidyMoney
afsOrder.SkuUserMoney += orderSku.UserMoney
afsOrder.Skus = append(afsOrder.Skus, orderSku)
orderSkuCount += utils.Float64TwoInt64(*sku.BuySaleQuantity)
}
}
}
if refundSkuCount == orderSkuCount {
afsOrder.RefundType = model.AfsTypeFullRefund
} else {
afsOrder.RefundType = model.AfsTypePartRefund
}
if afsOrder != nil {
//直接就来一个新的售后单,并且还是售后完成的
if orderStatus.Status == model.AfsOrderStatusFinished {
afsOrder.AfsFinishedAt = afsOrder.AfsCreatedAt
}
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)
}
cancelMsg := msg.(*tao_vegetable.UserCancelRefundApply)
for _, v := range afsOrder {
// 商家驳回,会发出用户撤销的回调通知,不管他
if v.AfsOrderID == cancelMsg.RefundId && v.Flag == model.AfsOrderFlagRefuseUserRefund {
return tao_vegetable.CallBackResultInfo(nil)
}
// 用户撤销未处理的售后订单
if v.AfsOrderID == cancelMsg.RefundId && v.Flag == 0 {
// 下面处理用户撤销售后
if err = utils.CallFuncLogError(func() error {
_, err = dao.DeleteEntity(db, v, "VendorOrderID", "VendorID")
return err
}, "SaveAfsOrder delete AfsOrder, afsOrderID:%s", v.AfsOrderID); err != nil {
return tao_vegetable.CallBackResultInfo(err)
}
// 删除售后商品
if err = utils.CallFuncLogError(func() error {
_, err = dao.DeleteEntity(db, &model.OrderSkuFinancial{
VendorOrderID: v.VendorOrderID,
VendorID: v.VendorID,
IsAfsOrder: 1,
}, "VendorOrderID", "VendorID", "IsAfsOrder")
return err
}, "SaveAfsOrder delete OrderSkuFinancial, afsOrderID:%s", v.AfsOrderID); err != nil {
return tao_vegetable.CallBackResultInfo(err)
}
}
}
}
if err := partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus); err == nil {
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")
}
}
}
globals.SugarLogger.Debugf("=============errr : %v", err)
return tao_vegetable.CallBackResultInfo(err)
}
func (c *PurchaseHandler) callbackAfsMsg2Status(status string, msg interface{}) (orderStatus *model.OrderStatus) {
orderStatus = &model.OrderStatus{
VendorID: model.VendorIDTaoVegetable,
OrderType: model.OrderTypeAfsOrder,
RefVendorID: model.VendorIDTaoVegetable,
}
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 = time.Now()
orderStatus.Remark = refundData.Remarks
orderStatus.VendorOrderID = refundData.RefundId
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 = time.Now()
orderStatus.VendorOrderID = refundData.RefundId
//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 = time.Now()
orderStatus.VendorOrderID = refundData.OutMainRefundId
}
order, _ := partner.CurOrderManager.LoadOrder2(orderStatus.RefVendorOrderID, model.VendorIDTaoVegetable)
if order != nil {
orderStatus.RefVendorOrderID = order.VendorOrderID
}
if orderStatus.VendorOrderID == "" {
orderStatus.VendorOrderID = orderStatus.RefVendorOrderID
}
return orderStatus
}
func (c *PurchaseHandler) GetAfsStatusFromVendorStatus(notifyType string) int {
status := AfsVendorStatus2StatusMap[notifyType]
//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) {
db := dao.GetDB()
if approveType == partner.AfsApproveTypeRefused {
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")
//}
} else if approveType == partner.AfsApproveTypeRefusedToRefundMoney {
return errors.New("此平台暂时不支持")
} else {
// 加载子订单号
orderDetail, _ := partner.CurOrderManager.LoadOrder(order.VendorOrderID, model.VendorIDTaoVegetable)
// 加载退款商品
afsSkuOrder, _ := dao.GetOrderRefundSkuList(db, []string{order.VendorOrderID})
param := &request3156.AlibabaTclsAelophyRefundAgreeRequest{
StoreId: utils.String2Pointer(order.VendorStoreID),
OutOrderId: utils.String2Pointer(orderDetail.VendorOrderID2),
RefundId: utils.String2Pointer(order.AfsOrderID),
OrderFrom: utils.Int64ToPointer(utils.Str2Int64(tao_vegetable.TaoVegetableChannelCode)),
}
// 加载购买商品
sku, _ := dao.GetSimpleOrderSkus(db, order.VendorOrderID, nil)
skuCount := 0
for _, v := range sku {
skuCount += v.Count
}
refundSkuCount := 0
subRefundList := make([]domain3156.AlibabaTclsAelophyRefundAgreeSubrefundlist, 0, len(afsSkuOrder))
for _, v := range afsSkuOrder {
subRefundList = append(subRefundList, domain3156.AlibabaTclsAelophyRefundAgreeSubrefundlist{
OutSubOrderId: utils.String2Pointer(v.VendorSubOrderID),
RefundFee: utils.Int64ToPointer(v.UserMoney),
})
refundSkuCount += v.Count
}
// 全退退运费
if skuCount == refundSkuCount {
}
param.SubRefundList = &subRefundList
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)
}
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.VendorIDTaoVegetable])
}
// 发起部分退款
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.VendorIDTaoVegetable); err == nil {
orderAfsInfo.AfsTotalShopMoney = order.TotalShopMoney + afsTotalShopMoney
}
return orderAfsInfo, err
}