Files
jx-callback/business/partner/purchase/jd/order.go
邹宗楠 474d3da18f 1
2025-11-10 09:52:12 +08:00

737 lines
30 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 jd
import (
"fmt"
"git.rosy.net.cn/baseapi/platformapi/tencent_map"
"regexp"
"strings"
"time"
"git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/baseapi/platformapi/jdapi"
"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 (
VendorStatus2StatusMap = map[string]int{
jdapi.OrderStatusPurchased: model.OrderStatusNew, // 新订单
jdapi.OrderStatusWaitOutStore: model.OrderStatusAccepted, // 已接单
jdapi.StatusIDWaitOutStore: model.OrderStatusAccepted, // 已接单
jdapi.OrderStatusFinishedPickup: model.OrderStatusFinishedPickup, // 拣货完成
jdapi.OrderStatusDelivering: model.OrderStatusDelivering,
jdapi.OrderStatusDelivered: model.OrderStatusFinished, // 订单完成
jdapi.OrderStatusFinished: model.OrderStatusFinished, // todo 这个状态不是真正都完成的意思?
jdapi.OrderStatusCanceled: model.OrderStatusCanceled, // 订单已经取消
jdapi.OrderStatusAdjust: model.OrderStatusAdjust, // 订单调整
jdapi.OrderStatusUserApplyCancel: model.OrderStatusApplyCancel,
jdapi.OrderStatusLocked: model.OrderStatusLocked,
jdapi.OrderStatusUnlocked: model.OrderStatusUnlocked,
jdapi.OrderStatusVenderAgreeCancel: model.OrderStatusVendorAgreeCancel, // 同意取消
jdapi.OrderStatusVenderRejectCancel: model.OrderStatusVendorRejectCancel, // 拒绝取消
jdapi.CallbackMsgOrderAddTips: model.OrderStatusWaybillTipChanged, // 小飞
}
deliveryTypeMap = map[int]string{
jdapi.CarrierNoCrowdSourcing: model.OrderDeliveryTypePlatform,
jdapi.CarrierNoSelfDelivery: model.OrderDeliveryTypeStoreSelf,
jdapi.CarrierNoSelfTake: model.OrderDeliveryTypeSelfTake,
}
selfTakeCodeReg = regexp.MustCompile(`等待用户凭提货码(\d+)于`)
afsMsgMap = map[string]bool{
jdapi.CallbackMsgNewApplyAfterSaleBill: true,
jdapi.CallbackMsgUpdateApplyAfterSaleBill: true,
jdapi.CallbackMsgNewAfterSaleBill: true,
jdapi.CallbackMsgAfterSaleBillStatus: true,
}
)
func (c *PurchaseHandler) OnOrderMsg(a *jdapi.API, msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
primaryID := msg.BillID
primaryID += utils.Int64ToStr(time.Now().Unix())
jxutils.CallMsgHandler(func() {
retVal = c.onOrderMsg(a, msg)
}, primaryID)
return retVal
}
func (c *PurchaseHandler) updateOrderFinancialInfo(a *jdapi.API, orderID string) (err error) {
order := &model.GoodsOrder{
VendorOrderID: orderID,
VendorID: model.VendorIDJD,
}
orderSettlement, err := a.OrderShoudSettlementService2(orderID)
if err == nil {
if orderSettlement != nil {
UpdateOrderBySettleMent(order, orderSettlement)
err = partner.CurOrderManager.UpdateOrderFields(order, []string{ /*"WaybillTipMoney", */ "TotalShopMoney", "PmSubsidyMoney", "NewEarningPrice"})
}
}
return err
}
func (c *PurchaseHandler) onOrderMsg(a *jdapi.API, msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
if afsMsgMap[msg.MsgURL] {
retVal = c.OnAfsOrderMsg(a, msg)
} else {
status := c.callbackMsg2Status(msg)
if jdapi.StatusIDNewOrder == msg.StatusID {
status.Status = model.OrderStatusNew // 因为京东将事件32000与状态32000混用事件32000可能是新订单也可能是已接单统一当成新订单处理
}
if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 {
return nil
}
if msg.MsgURL == jdapi.CallbackMsgOrderAccounting {
retVal = c.OnFinancialMsg(msg)
retVal = jdapi.Err2CallbackResponse(c.updateOrderFinancialInfo(a, msg.BillID), status.VendorStatus)
} else {
// 新订单事件,与订单状态有点冲突
if jdapi.StatusIDNewOrder == msg.StatusID {
retVal = c.onOrderNew(a, msg, status)
} else if jdapi.OrderStatusAdjust == msg.StatusID {
retVal = c.onOrderAdjust(a, msg, status)
} else {
if msg.StatusID == jdapi.OrderStatusAddComment || msg.StatusID == jdapi.OrderStatusModifyComment {
utils.CallFuncAsync(func() {
c.onOrderComment2(a, msg)
})
}
// if msg.StatusID == jdapi.OrderStatusVenderAgreeCancel {
// order := &model.GoodsOrder{
// VendorOrgCode: vendorOrgCode,
// VendorOrderID: msg.BillID,
// }
// err2 := c.PickupGoods(order, false, jxcontext.AdminCtx.GetUserName())
// if err2 != nil {
// globals.SugarLogger.Warnf("京东取消拣货:%v", err2)
// }
// }
err := partner.CurOrderManager.OnOrderStatusChanged(AppKey2OrgCode(msg.AppKey), status)
retVal = jdapi.Err2CallbackResponse(err, status.VendorStatus)
}
}
if status.Status == model.OrderStatusFinished {
c.OnFinancialMsg(msg)
jdapi.Err2CallbackResponse(c.updateOrderFinancialInfo(a, msg.BillID), status.VendorStatus)
}
}
return retVal
}
func (c *PurchaseHandler) OnOrderInfoChangeMsg(vendorOrgCode string, msg *jdapi.CallbackOrderInfoChangeMsg) (retVal *jdapi.CallbackResponse) {
jxutils.CallMsgHandler(func() {
retVal = c.onOrderInfoChangeMsg(vendorOrgCode, msg)
}, jxutils.ComposeUniversalOrderID(msg.BillID, model.VendorIDJD))
return retVal
}
func (c *PurchaseHandler) onOrderInfoChangeMsg(vendorOrgCode string, msg *jdapi.CallbackOrderInfoChangeMsg) (retVal *jdapi.CallbackResponse) {
db := dao.GetDB()
order, err := dao.GetSimpleOrder(db, msg.BillID)
if err == nil {
//任意一项变了
if order.AdjustCount < 3 {
if msg.BuyerFullAddress != order.ConsigneeAddress || msg.BuyerFullName != order.ConsigneeName || msg.BuyerMobile != order.ConsigneeMobile ||
jxutils.StandardCoordinate2Int(utils.Str2Float64(msg.BuyerLat)) != order.ConsigneeLat || jxutils.StandardCoordinate2Int(utils.Str2Float64(msg.BuyerLng)) != order.ConsigneeLng ||
msg.OrderBuyerRemark != order.BuyerComment {
if order.Status <= model.OrderStatusDelivering {
if err = weixinmsg.NotifyOrderChanged(order); err == nil {
if msg.BuyerFullAddress != "" {
order.ConsigneeAddress = msg.BuyerFullAddress
}
if msg.BuyerFullName != "" {
order.ConsigneeName = msg.BuyerFullName
}
if msg.BuyerMobile != "" {
order.ConsigneeMobile = msg.BuyerMobile
}
if msg.BuyerLat != "" {
order.ConsigneeLat = jxutils.StandardCoordinate2Int(utils.Str2Float64(msg.BuyerLat))
}
if msg.BuyerLng != "" {
order.ConsigneeLng = jxutils.StandardCoordinate2Int(utils.Str2Float64(msg.BuyerLng))
}
if msg.OrderBuyerRemark != "" {
order.BuyerComment = msg.OrderBuyerRemark
}
order.AdjustCount++
_, err = dao.UpdateEntity(db, order, "ConsigneeAddress", "ConsigneeName", "ConsigneeMobile", "ConsigneeLat", "ConsigneeLng", "BuyerComment", "AdjustCount")
}
}
}
}
}
return jdapi.SuccessResponse
}
func UpdateOrderBySettleMent(order *model.GoodsOrder, orderSettlement *jdapi.OrderSettlementInfo) {
if orderSettlement != nil {
order.TotalShopMoney = orderSettlement.SettlementAmount
order.PmSubsidyMoney = orderSettlement.PlatOrderGoodsDiscountMoney + orderSettlement.PlatSkuGoodsDiscountMoney
if order.TotalShopMoney > 0 {
if order2, _ := partner.CurOrderManager.LoadOrder(order.VendorOrderID, order.VendorID); order2 != nil {
if order2.EarningType == model.EarningTypePoints {
order.NewEarningPrice = order.TotalShopMoney * int64((100 - order2.OrderPayPercentage/2)) / 100
} else {
order.NewEarningPrice = order2.EarningPrice
}
}
} else {
order.NewEarningPrice = order.EarningPrice
}
}
}
func (c *PurchaseHandler) getOrder(a *jdapi.API, orderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) {
var (
realMobile string
orderSettlement *jdapi.OrderSettlementInfo
)
task := tasksch.NewParallelTask("jd getOrder", tasksch.NewParallelConfig().SetIsContinueWhenError(true), jxcontext.AdminCtx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
taskIndex := batchItemList[0].(int)
switch taskIndex {
case 0:
orderMap, err = a.QuerySingleOrder(orderID)
if err == nil {
order = c.Map2Order(orderMap)
if configs, err := dao.QueryConfigs(dao.GetDB(), "jdStorePageCookie", model.ConfigTypeCookie, ""); err == nil {
//a.SetJdCookie(configs[0].Value)
a.SetCookieWithStr(configs[0].Value)
}
realMobile, err = a.GetRealMobile4Order(orderID, order.VendorStoreID)
if err == nil && realMobile != "" {
order.ConsigneeMobile2 = jxutils.FormalizeMobile(realMobile)
} else {
// if strings.Contains(err.Error(), "用户登陆") {
// globals.SugarLogger.Warnf("jd 获取真实号cookie可能过期了")
// }
err = nil
}
}
case 1:
orderSettlement, _ = a.OrderShoudSettlementService2(orderID)
}
return nil, err
}, []int{0, 1})
task.Run()
_, err = task.GetResult(0)
if order != nil && orderSettlement != nil {
UpdateOrderBySettleMent(order, orderSettlement)
err = partner.CurOrderManager.UpdateOrderFields(order, []string{"NewEarningPrice", "TotalShopMoney"})
}
return order, orderMap, err
}
func (c *PurchaseHandler) GetOrder(vendorOrgCode, orderID, vendorStoreID string) (order *model.GoodsOrder, err error) {
order, _, err = c.getOrder(getAPI(vendorOrgCode), orderID)
return order, err
}
func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) {
order, err := getAPI(vendorOrgCode).QuerySingleOrder2(vendorOrderID)
if err == nil {
status = getStatusFromVendorStatus(utils.Int2Str(order.OrderStatus))
}
return status, err
}
func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
return Map2Order(orderData)
}
func Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
result := orderData
orderID := utils.Int64ToStr(utils.MustInterface2Int64(result["orderId"]))
const defaultStatusTimeField = "orderPurchaseTime"
statusTimeField := defaultStatusTimeField
if result[statusTimeField] == nil { // 814560888003021 orderPurchaseTime为空
statusTimeField = "orderStartTime"
}
//物竞天择订单备注改一下
comment := utils.TrimBlankChar(utils.Interface2String(result["orderBuyerRemark"]))
if strings.Contains(comment, "【JD】") {
comment += "【京东商城】"
}
order = &model.GoodsOrder{
VendorOrderID: orderID,
VendorID: model.VendorIDJD,
VendorStoreID: utils.Interface2String(result["produceStationNo"]),
StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["produceStationNoIsv"]), 0)),
StoreName: utils.Interface2String(result["produceStationName"]),
VendorUserID: utils.Interface2String(result["buyerPin"]),
ConsigneeName: utils.Interface2String(result["buyerFullName"]),
ConsigneeMobile: jxutils.FormalizeMobile(utils.Interface2String(result["buyerMobile"])),
ConsigneeAddress: utils.Interface2String(result["buyerFullAddress"]),
CoordinateType: model.CoordinateTypeMars,
BuyerComment: comment,
ExpectedDeliveredTime: utils.Str2TimeWithDefault(utils.Interface2String(result["orderPreEndDeliveryTime"]), utils.DefaultTimeValue),
PickDeadline: utils.Str2TimeWithDefault(utils.Interface2String(result["pickDeadline"]), utils.DefaultTimeValue), // 813951615000022 pickDeadline为空
VendorStatus: utils.Int64ToStr(utils.MustInterface2Int64(result["orderStatus"])),
OrderSeq: int(utils.MustInterface2Int64(result["orderNum"])),
StatusTime: utils.Str2Time(result[statusTimeField].(string)),
OrderCreatedAt: utils.Str2Time(result[statusTimeField].(string)),
// OrderFinishedAt: utils.Str2Time(result["orderStatusTime"].(string)),
OriginalData: string(utils.MustMarshal(result)),
ActualPayPrice: utils.MustInterface2Int64(result["orderBuyerPayableMoney"]),
BaseFreightMoney: utils.Interface2Int64WithDefault(result["orderBaseFreightMoney"], 0),
DistanceFreightMoney: utils.Interface2Int64WithDefault(result["merchantPaymentDistanceFreightMoney"], 0),
DeliveryType: deliveryTypeMap[int(utils.Str2Int64WithDefault(utils.Interface2String(result["deliveryCarrierNo"]), 0))],
VendorOrgCode: utils.Interface2String(result["orgCode"]),
}
if orderInvoice, ok := result["orderInvoice"].(map[string]interface{}); ok && orderInvoice != nil {
order.InvoiceTitle = utils.Interface2String(orderInvoice["invoiceTitle"])
order.InvoiceTaxerID = utils.Interface2String(orderInvoice["invoiceDutyNo"])
order.InvoiceEmail = utils.Interface2String(orderInvoice["invoiceMail"])
}
order.Status = getStatusFromVendorStatus(order.VendorStatus)
businessTage := utils.Interface2String(result["businessTag"])
if strings.Index(businessTage, "dj_aging_immediately") >= 0 {
order.BusinessType = model.BusinessTypeImmediate
} else {
order.BusinessType = model.BusinessTypeDingshida
}
coordinateType := utils.Interface2Int64WithDefault(result["buyerCoordType"], 1)
originalLng := utils.MustInterface2Float64(result["buyerLng"])
originalLat := utils.MustInterface2Float64(result["buyerLat"])
if coordinateType == 1 {
//lng, lat, err2 := api.TencentMapAPI.TencentCoordinateChange(originalLng, originalLat, autonavi.CoordSysGPS)
originalPoint, err2 := api.TencentMapAPI.TencentCoordinateChange(&tencent_map.TencentCoordinateChangeReq{
Locations: fmt.Sprintf("%.6f,%.6f", originalLat, originalLng),
Type: tencent_map.CoordinateChangeTypeGPS,
})
if err2 == nil && len(originalPoint) != 0 {
//originalLng = lng
//originalLat = lat
originalLng = utils.Str2Float64(originalPoint[0].Lng)
originalLat = utils.Str2Float64(originalPoint[0].Lat)
} else {
// 如果没有转成功,保留原始数据
order.CoordinateType = model.CoordinateTypeGPS
}
}
order.ConsigneeLng = jxutils.StandardCoordinate2Int(originalLng)
order.ConsigneeLat = jxutils.StandardCoordinate2Int(originalLat)
discounts, _ := result["discount"].([]interface{})
for _, v := range discounts {
discount := v.(map[string]interface{})
order.DiscountMoney += utils.Interface2Int64WithDefault(discount["discountPrice"], 0)
}
for _, product2 := range result["product"].([]interface{}) {
product := product2.(map[string]interface{})
sku := &model.OrderSku{
VendorOrderID: orderID,
VendorID: model.VendorIDJD,
Count: int(utils.MustInterface2Int64(product["skuCount"])),
SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product["skuIdIsv"]), 0)),
VendorSkuID: utils.Int64ToStr(utils.MustInterface2Int64(product["skuId"])),
SkuName: product["skuName"].(string),
Weight: jxutils.FloatWeight2Int(float32(utils.MustInterface2Float64(product["skuWeight"]))),
VendorPrice: utils.MustInterface2Int64(product["skuStorePrice"]),
SalePrice: utils.MustInterface2Int64(product["skuJdPrice"]),
}
if product["upcCode"] != nil && product["upcCode"].(string) != "" {
sku.Upc = product["upcCode"].(string)
}
if jdPromotionType := int(utils.MustInterface2Int64(product["promotionType"])); jdPromotionType != 0 && jdPromotionType != jdapi.PromotionTypeNormal {
sku.StoreSubName = utils.Int2Str(jdPromotionType)
}
if skuCostumeProperty, ok := product["skuCostumeProperty"]; ok {
sku.SkuName += skuCostumeProperty.(string)
}
if isGift, ok := product["isGift"].(bool); ok && isGift {
sku.SkuType = 1
}
order.Skus = append(order.Skus, sku)
}
// 包装袋金额设置
store, _ := dao.GetStoreDetailByVendorStoreID(dao.GetDB(), order.VendorStoreID, order.VendorID, order.VendorOrgCode)
order.PackagePrice = store.PackageSetting
order.JxStoreID = store.ID
jxutils.RefreshOrderSkuRelated(order)
return order
}
//
func (c *PurchaseHandler) onOrderNew(a *jdapi.API, msg *jdapi.CallbackOrderMsg, orderStatus *model.OrderStatus) (response *jdapi.CallbackResponse) {
order, orderMap, err := c.getOrder(a, msg.BillID)
if err == nil {
if err = partner.CurOrderManager.OnOrderNew(order, orderStatus); err == nil {
utils.CallFuncAsync(func() {
c.OnOrderDetail(a, orderMap, partner.CreatedPeration)
})
}
}
return jdapi.Err2CallbackResponse(err, "jd onOrderNew")
}
func (c *PurchaseHandler) onOrderAdjust(a *jdapi.API, msg *jdapi.CallbackOrderMsg, orderStatus *model.OrderStatus) *jdapi.CallbackResponse {
order, orderMap, err := c.getOrder(a, msg.BillID)
if err == nil {
err = partner.CurOrderManager.OnOrderAdjust(order, orderStatus)
if err == nil {
utils.CallFuncAsync(func() {
c.OnOrderDetail(a, orderMap, partner.UpdatedPeration)
})
}
}
return jdapi.Err2CallbackResponse(err, "jd onOrderAdjust")
}
func (c *PurchaseHandler) callbackMsg2Status(msg *jdapi.CallbackOrderMsg) *model.OrderStatus {
orderStatus := &model.OrderStatus{
VendorOrderID: msg.BillID,
VendorID: model.VendorIDJD,
OrderType: model.OrderTypeOrder,
RefVendorOrderID: msg.BillID,
RefVendorID: model.VendorIDJD,
VendorStatus: msg.StatusID,
StatusTime: utils.Str2Time(msg.Timestamp),
Remark: msg.Remark,
}
if msg.MsgURL == jdapi.CallbackMsgOrderAddTips {
orderStatus.VendorStatus = jdapi.CallbackMsgOrderAddTips
}
orderStatus.Status = getStatusFromVendorStatus(orderStatus.VendorStatus)
//todo 获取门店配送方式 京东京东
order, _, err := dao.GetOrders(dao.GetDB(), nil, false, false, "", "", false, nil, false, "", map[string]interface{}{
"vendorOrderID": orderStatus.VendorOrderID,
}, 0, 0)
if err == nil && len(order) > 0 {
if order[0].DeliveryType == model.OrderDeliveryTypeStoreSelf && orderStatus.Status == model.OrderStatusDelivering { //门店自送且在配送中
orderStatus.Status = model.OrderStatusFinishedPickup //修改为捡货完成
}
globals.SugarLogger.Debugf("jdjd callbackMsg2Status status=%d,vendorStatus=%s", orderStatus.Status, orderStatus.VendorStatus)
}
return orderStatus
}
func (c *PurchaseHandler) postFakeMsg(vendorOrgCode, vendorOrderID, vendorStatus string) {
a := getAPI(vendorOrgCode)
msg := &jdapi.CallbackOrderMsg{
CallbackMsg: &jdapi.CallbackMsg{
AppKey: a.GetAppKey(),
},
BillID: vendorOrderID,
StatusID: vendorStatus,
Timestamp: utils.Time2Str(time.Now()),
}
utils.CallFuncAsync(func() {
OnOrderMsg(msg, a)
})
}
// IPurchasePlatformHandler
func getStatusFromVendorStatus(vendorStatus string) int {
if status, ok := VendorStatus2StatusMap[vendorStatus]; ok {
return status
}
return model.OrderStatusUnknown
}
func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
if globals.EnableJdStoreWrite {
err = getAPI(order.VendorOrgCode).OrderAcceptOperate(order.VendorOrderID, isAcceptIt, userName)
if isAcceptIt && err == nil {
c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.StatusIDWaitOutStore)
}
} else {
if isAcceptIt {
c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.StatusIDWaitOutStore)
} else {
c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.OrderStatusCanceled)
}
}
return err
}
func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
isSelfDelivery = model.IsOrderDeliveryByStore(order) || model.IsOrderDeliveryBySelf(order)
if !isSelfDelivery && globals.EnableJdStoreWrite {
_, err = getAPI(order.VendorOrgCode).OrderJDZBDelivery(order.VendorOrderID, userName)
} else {
switch order.DeliveryType {
case model.OrderDeliveryTypeStoreSelf: // 商家配送
_, err = getAPI(order.VendorOrgCode).OrderJDZBStoreDelivery(order.VendorOrderID, userName)
case model.OrderDeliveryTypeSelfTake: // 用户自提
_, err = getAPI(order.VendorOrgCode).OrderJDZBSelfDelivery(order.VendorOrderID, userName)
}
c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.OrderStatusFinishedPickup)
}
if err == nil {
orderSettlement, _ := getAPI(order.VendorOrgCode).OrderShoudSettlementService2(order.VendorOrderID)
UpdateOrderBySettleMent(order, orderSettlement)
err = partner.CurOrderManager.UpdateOrderFields(order, []string{"NewEarningPrice", "TotalShopMoney"})
}
return err
}
func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) {
if globals.EnableJdStoreWrite {
err = getAPI(order.VendorOrgCode).ReceiveFailedAudit(order.VendorOrderID, isAcceptIt, ctx.GetUserName(), "")
}
return err
}
func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送
if globals.EnableJdStoreWrite {
err = getAPI(order.VendorOrgCode).UrgeDispatching(order.VendorOrderID, ctx.GetUserName())
}
return err
}
func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货
if globals.EnableJdStoreWrite {
err = getAPI(order.VendorOrgCode).ConfirmReceiveGoods(order.VendorOrderID)
}
return err
}
func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
if globals.EnableJdStoreWrite {
if order.VendorOrgCode == jdapi.ModifySellerDeliveryNo { // 自配送门店不需要达达配送转自送
return err
}
_, err = getAPI(order.VendorOrgCode).ModifySellerDelivery(order.VendorOrderID, userName)
if err != nil {
if errWithCode, ok := err.(*utils.ErrorWithCode); ok && errWithCode.Level() == 1 {
if order2, err2 := c.GetOrder(order.VendorOrgCode, order.VendorOrderID, ""); err2 == nil {
var mapData map[string]interface{}
if err2 = utils.UnmarshalUseNumber([]byte(order2.OriginalData), &mapData); err2 == nil {
if utils.Interface2String(mapData["deliveryCarrierNo"]) == "2938" { // 当前已经是自送状态了
err = nil
}
}
}
}
}
}
return err
}
func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) {
if globals.EnableJdStoreWrite {
_, err = getAPI(order.VendorOrgCode).DeliveryEndOrder(order.VendorOrderID, userName)
}
return err
}
func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
if globals.EnableJdStoreWrite {
_, err = getAPI(order.VendorOrgCode).OrderSerllerDelivery(order.VendorOrderID, userName)
}
return err
}
// 京东送达接口都是一样的
func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
if globals.EnableJdStoreWrite {
err = c.Swtich2SelfDelivered(order, userName)
}
return err
}
func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) {
mobile, err = getAPI(order.VendorOrgCode).GetRealMobile4Order(order.VendorOrderID, order.VendorStoreID)
return mobile, err
}
func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
if globals.EnableJdStoreWrite {
err = getAPI(order.VendorOrgCode).OrderCancelOperate(order.VendorOrderID, isAgree, ctx.GetUserName(), reason)
}
return err
}
func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
if globals.EnableJdStoreWrite {
err1 := c.Swtich2SelfDeliver(order, ctx.GetUserName())
if err = getAPI(order.VendorOrgCode).CancelAndRefund(order.VendorOrderID, ctx.GetUserName(), reason); err != nil {
if err1 != nil {
err = fmt.Errorf("取消订单失败,京东取消订单是要先转为自送再处理,转自送失败:%v", err1)
}
}
}
return err
}
func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
order = jxutils.RemoveSkuFromOrder(order, removedSkuList)
var oaosAdjustDTOList []*jdapi.OAOSAdjustDTO
dtoMap := make(map[int]*jdapi.OAOSAdjustDTO)
for _, sku := range order.Skus {
skuID := jxutils.GetSkuIDFromOrderSku(sku)
if dtoMap[skuID] == nil {
dtoMap[skuID] = &jdapi.OAOSAdjustDTO{
OutSkuID: utils.Int2Str(skuID),
SkuCount: sku.Count,
}
oaosAdjustDTOList = append(oaosAdjustDTOList, dtoMap[skuID])
} else {
dtoMap[skuID].SkuCount += sku.Count
}
}
if globals.EnableJdStoreWrite {
err = getAPI(order.VendorOrgCode).AdjustOrder(order.VendorOrderID, ctx.GetUserName(), reason, oaosAdjustDTOList)
}
return err
}
func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) {
if utils.IsTimeZero(queryDate) {
return nil, fmt.Errorf("queryDate必须指定")
}
fromDate := utils.Time2Date(queryDate)
toDate := fromDate.Add(24*time.Hour - 1)
queryParam := &jdapi.OrderQueryParam{
OrderPurchaseTimeBegin: utils.Time2Str(fromDate),
OrderPurchaseTimeEnd: utils.Time2Str(toDate),
PageNo: jdapi.AllPage,
}
if vendorStoreID != "" {
queryParam.DeliveryStationNo = vendorStoreID
}
orderList, _, err := getAPI(vendorOrgCode).OrderQuery2(queryParam)
if err == nil {
vendorOrderIDs = make([]string, len(orderList))
for k, v := range orderList {
vendorOrderIDs[k] = utils.Int64ToStr(v.OrderID)
}
}
return vendorOrderIDs, err
}
func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) {
orderInfo, err := getAPI(vendorOrgCode).QuerySingleOrder2(vendorOrderID)
if err == nil {
tipFee = int64(orderInfo.Tips)
}
return tipFee, err
}
func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) {
//curTipFee, err := c.GetWaybillTip(ctx, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2)
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJD)
if err == nil {
curTipFee := order.WaybillTipMoney
if tipFee2Add := tipFee - curTipFee; tipFee2Add > 0 {
if globals.EnableJdStoreWrite {
err = getAPI(vendorOrgCode).OrderAddTips(vendorOrderID, int(tipFee2Add), ctx.GetUserName())
}
}
}
return err
}
func (c *PurchaseHandler) GetSelfTakeCode(ctx *jxcontext.Context, order *model.GoodsOrder) (selfTakeCode string, err error) {
orderTrackList, err := getAPI(order.VendorOrgCode).GetByOrderNoForOaos(order.VendorOrderID)
if err == nil {
for _, v := range orderTrackList {
if v.TagCode == 180 {
searchResult := selfTakeCodeReg.FindStringSubmatch(v.MsgContent)
if searchResult != nil && len(searchResult[1]) > 0 {
selfTakeCode = searchResult[1]
}
break
}
}
}
return selfTakeCode, err
}
func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) {
if globals.EnableJdStoreWrite {
err = getAPI(order.VendorOrgCode).CheckSelfPickCode(selfTakeCode, order.VendorOrderID, ctx.GetUserName())
}
return err
}
func (c *PurchaseHandler) ComplaintRider(vendorOrderId string, resonID int, resonContent string) (err error) {
if globals.EnableJdStoreWrite {
order, _ := partner.CurOrderManager.LoadOrder(vendorOrderId, model.VendorIDJD)
err = getAPI(order.VendorOrgCode).ComplaintDadaDeliver(vendorOrderId, resonID)
}
return err
}
// 转自配送时取消非专送混合送门店取消理由
func (c *PurchaseHandler) GetCancelDeliveryReason(order *model.GoodsOrder) (string, error) {
return "", nil
}
// 取消美团外卖理由转使用三方配送
func (c *PurchaseHandler) CancelLogisticsByWmOrderId(order *model.GoodsOrder, reasonCode, detailContent, appPoiCode, orderId string) error {
return nil
}
// 获取订单配送状态
func (c *PurchaseHandler) OrderLogisticsStatus(orderId string) (*utils.RiderInfo, error) {
return nil, nil
}
// GetOrderSettleAccounts 获取订单结算信息
func (c *PurchaseHandler) GetOrderSettleAccounts(goods *model.GoodsOrder) (int64, error) {
settlement, err := getAPI(goods.VendorOrgCode).OrderShoudSettlementService2(goods.VendorOrderID)
if err != nil {
return 0, err
}
return settlement.SettlementAmount, nil
}
// GetPlatformLogisticsFee 获取自配送订单的配送费
func (c *PurchaseHandler) GetPlatformLogisticsFee(order *model.GoodsOrder) (int64, error) {
return 0, nil
}
// ApplyCompensationOrder 订单索赔
func (c *PurchaseHandler) ApplyCompensationOrder(order *model.GoodsOrder) (string, error) {
return "", nil
}
// UploadInvoice 回复用户发票申请
func (c *PurchaseHandler) UploadInvoice(param *model.InvoiceMsg, base64 string) ([]string, []string, error) {
order, _ := partner.CurOrderManager.LoadOrder(param.OrderId, model.VendorIDJD)
storeDetail, err := partner.CurOrderManager.LoadStoreDetail(order.JxStoreID, model.VendorIDJD)
if err != nil {
return nil, nil, err
}
if storeDetail == nil {
return nil, nil, fmt.Errorf("未查询到门店[%d]", order.JxStoreID)
}
if storeDetail.LicenceCode == "" {
return nil, nil, fmt.Errorf("未查询到门店营业执照编号,请天假门店营业执照信息[%s]", storeDetail.Name)
}
blue := &jdapi.BlueTicketParam{
OrderId: order.VendorOrderID,
ReceiverTaxNo: storeDetail.LicenceCode,
ReceiverName: storeDetail.Name,
InvoiceCode: param.InvoiceId,
IvcTitle: "个人", // 4-个人,5-公司
TotalPrice: utils.Float64ToStr(float64(param.InvoiceAmount) / float64(100)),
InvoiceTime: utils.Time2DateStr(time.Now()),
PdfInfo: base64,
FullEleInvoiceNo: param.InvoiceId,
}
return nil, nil, getAPI(order.VendorOrgCode).UploadBlueTicket(blue)
}