package tao_vegetable import ( "errors" "fmt" "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" "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) 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 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), RefundType: model.AfsTypeFullRefund, VendorOrgCode: refundData.MerchantCode, } 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 = *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.Float64TwoInt(*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 { //直接就来一个新的售后单,并且还是售后完成的 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) } 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 { 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 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.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 = time.Now() 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 = time.Now() orderStatus.VendorOrderID = refundData.BizSubRefundId } 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) { 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 } // 确认收到退货 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 }