1
This commit is contained in:
265
business/partner/purchase/tao_vegetable/act.go
Normal file
265
business/partner/purchase/tao_vegetable/act.go
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"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/jxutils/tasksch"
|
||||||
|
"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/business/partner/putils"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func jxActType2Mtwm(actType int) int {
|
||||||
|
if actType == model.ActSkuDirectDown {
|
||||||
|
actType = mtwmapi.RetailActTypeDirectDown
|
||||||
|
} else if actType == model.ActSkuSecKill {
|
||||||
|
actType = mtwmapi.RetailActTypeSecKill
|
||||||
|
} else {
|
||||||
|
actType = 0
|
||||||
|
}
|
||||||
|
return actType
|
||||||
|
}
|
||||||
|
|
||||||
|
func actOrderRules2Mtwm(actOrderRules []*model.ActOrderRule) (actDetails []*mtwmapi.FullDiscountActDetail) {
|
||||||
|
for _, v := range actOrderRules {
|
||||||
|
actDetails = append(actDetails, &mtwmapi.FullDiscountActDetail{
|
||||||
|
OriginalPrice: jxutils.IntPrice2Standard(v.SalePrice),
|
||||||
|
ActPrice: jxutils.IntPrice2Standard(v.DeductPrice),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return actDetails
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeSku2ActData(act *model.Act2, actStoreSku []*model.ActStoreSku2, handler func(int8) bool) (actData []*mtwmapi.RetailDiscountActData) {
|
||||||
|
orderLimit := 1
|
||||||
|
if act.LimitCount > 0 {
|
||||||
|
orderLimit = act.LimitCount
|
||||||
|
}
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
if handler == nil || handler(v.SyncStatus) {
|
||||||
|
dayLimit := -1
|
||||||
|
if v.Stock > 0 {
|
||||||
|
dayLimit = v.Stock
|
||||||
|
}
|
||||||
|
actData = append(actData, &mtwmapi.RetailDiscountActData{
|
||||||
|
AppFoodCode: utils.Int2Str(v.SkuID),
|
||||||
|
// UserType: 0,
|
||||||
|
StartTime: act.BeginAt.Unix(),
|
||||||
|
EndTime: act.EndAt.Unix(),
|
||||||
|
OrderLimit: orderLimit,
|
||||||
|
DayLimit: dayLimit,
|
||||||
|
// Period: "",
|
||||||
|
// WeeksTime: "",
|
||||||
|
SettingType: mtwmapi.SettingTypeAsPrice,
|
||||||
|
ActPrice: jxutils.IntPrice2Standard(v.ActualActPrice),
|
||||||
|
// DiscountCoefficient: 0,
|
||||||
|
// Sequence: int(v.ActPrice), // 此字段不允许重复
|
||||||
|
// ItemID: utils.Str2Int64WithDefault(v.VendorActID, 0),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actData
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeSku2ActData4Delete(actStoreSku []*model.ActStoreSku2, handler func(int8) bool) (actIDList []string) {
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
if handler == nil || handler(v.SyncStatus) {
|
||||||
|
if v.VendorActID != "" {
|
||||||
|
actIDList = append(actIDList, v.VendorActID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actIDList
|
||||||
|
}
|
||||||
|
|
||||||
|
func isCreateOrUpdate(syncStatus int8) bool {
|
||||||
|
return model.IsSyncStatusNeedCreate(syncStatus) || model.IsSyncStatusNeedUpdate(syncStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*model.ActStoreSku2) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||||
|
actData := storeSku2ActData(act, actStoreSku, isCreateOrUpdate)
|
||||||
|
if len(actData) > 0 {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
actResult, faileInfoList, err2 := api.MtwmAPI.RetailDiscountBatchSave2(vendorStoreID, jxActType2Mtwm(act.Type), actData)
|
||||||
|
err = err2
|
||||||
|
// 忽略错误,都放在failedList里
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
actStoreSkuMap := make(map[int]*model.ActStoreSku2)
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
actStoreSkuMap[v.SkuID] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range actResult {
|
||||||
|
if v2 := actStoreSkuMap[int(utils.Str2Int64WithDefault(v.AppFoodCode, 0))]; v2 != nil {
|
||||||
|
v2.VendorActID = utils.Int64ToStr(v.ActID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, v := range faileInfoList {
|
||||||
|
if v2 := actStoreSkuMap[int(utils.Str2Int64WithDefault(v.AppFoodCode, 0))]; v2 != nil {
|
||||||
|
failedList = append(failedList, &partner.StoreSkuInfoWithErr{
|
||||||
|
StoreSkuInfo: &partner.StoreSkuInfo{
|
||||||
|
SkuID: v2.SkuID,
|
||||||
|
},
|
||||||
|
VendoreID: model.VendorIDMTWM,
|
||||||
|
StoreID: int(utils.Str2Int64WithDefault(vendorStoreID, 0)),
|
||||||
|
ErrMsg: v.ErrorMsg,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
v.VendorActID = utils.Int64ToStr(jxutils.GenFakeID())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return failedList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func cancelOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*model.ActStoreSku2) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||||
|
if list := storeSku2ActData4Delete(actStoreSku, nil /*model.IsSyncStatusNeedDelete*/); len(list) > 0 {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
failedList2, err2 := api.MtwmAPI.RetailDiscountDelete2(vendorStoreID, jxActType2Mtwm(act.Type), list)
|
||||||
|
actStoreSkuMap := make(map[string]*model.ActStoreSku2)
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
actStoreSkuMap[v.VendorActID] = v
|
||||||
|
}
|
||||||
|
for _, v := range failedList2 {
|
||||||
|
if !mtwmapi.CanDeleteActErrMsgIgnore(v.ErrorMsg) {
|
||||||
|
failedList = append(failedList, &partner.StoreSkuInfoWithErr{
|
||||||
|
StoreSkuInfo: &partner.StoreSkuInfo{
|
||||||
|
SkuID: actStoreSkuMap[utils.Int64ToStr(v.ActID)].SkuID,
|
||||||
|
},
|
||||||
|
StoreID: int(utils.Str2Int64WithDefault(vendorStoreID, 0)),
|
||||||
|
ErrMsg: v.ErrorMsg,
|
||||||
|
VendoreID: model.VendorIDMTWM,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = err2
|
||||||
|
err = nil // 强制不返回错误,使用部分错误
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return failedList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getActStoreSkuFromTaskResult(taskReslt []interface{}) (list []*model.ActStoreSku2) {
|
||||||
|
for _, v := range taskReslt {
|
||||||
|
actStoreSkuList := v.([]*model.ActStoreSku2)
|
||||||
|
list = append(list, actStoreSkuList...)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
func createSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (createdList []*model.ActStoreSku2, err error) {
|
||||||
|
actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku)
|
||||||
|
task := tasksch.NewParallelTask("mtwm createSkuAct", nil, ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
list := batchItemList[0].([]*model.ActStoreSku2)
|
||||||
|
failedList, err2 := createOneShopAct(act, list[0].VendorStoreID, list)
|
||||||
|
if err = err2; err2 == nil {
|
||||||
|
if len(failedList) > 0 {
|
||||||
|
failedMap := putils.StoreSkuInfoWithErrList2MapBySku(failedList)
|
||||||
|
list = []*model.ActStoreSku2{}
|
||||||
|
for _, v := range actStoreSku {
|
||||||
|
if failedMap[v.SkuID] == nil {
|
||||||
|
list = append(list, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = []*model.ActStoreSku2{}
|
||||||
|
}
|
||||||
|
retVal = []interface{}{list}
|
||||||
|
}
|
||||||
|
return retVal, err
|
||||||
|
}, actStoreSkuListList)
|
||||||
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
|
result, err := task.GetResult(0)
|
||||||
|
return getActStoreSkuFromTaskResult(result), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func cancelSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (canceledList []*model.ActStoreSku2, err error) {
|
||||||
|
actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku)
|
||||||
|
task := tasksch.NewParallelTask("mtwm cancelSkuAct", nil, ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
actStoreSkuList := batchItemList[0].([]*model.ActStoreSku2)
|
||||||
|
if _, err = cancelOneShopAct(act, actStoreSkuList[0].VendorStoreID, actStoreSkuList); err == nil {
|
||||||
|
retVal = []interface{}{actStoreSkuList}
|
||||||
|
}
|
||||||
|
return retVal, err
|
||||||
|
}, actStoreSkuListList)
|
||||||
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
|
result, err := task.GetResult(0)
|
||||||
|
return getActStoreSkuFromTaskResult(result), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) {
|
||||||
|
var actStoreSkuList4Create, actStoreSkuList4Delete []*model.ActStoreSku2
|
||||||
|
var updateItems []*dao.KVUpdateItem
|
||||||
|
|
||||||
|
actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuList)
|
||||||
|
for storeID := range actStoreSkuMap {
|
||||||
|
for _, actStoreSku := range actStoreSkuMap[storeID] {
|
||||||
|
if model.IsSyncStatusDelete(actStoreSku.SyncStatus) {
|
||||||
|
actStoreSkuList4Delete = append(actStoreSkuList4Delete, actStoreSku)
|
||||||
|
} else if model.IsSyncStatusNew(actStoreSku.SyncStatus) {
|
||||||
|
actStoreSkuList4Create = append(actStoreSkuList4Create, actStoreSku)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = func() (err error) {
|
||||||
|
if model.IsSyncStatusDelete(act.SyncStatus) {
|
||||||
|
canceledList, err2 := cancelSkuAct(ctx, nil, act, actStoreSkuList)
|
||||||
|
updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, canceledList, model.SyncFlagModifiedMask)...)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask))
|
||||||
|
}
|
||||||
|
} else if model.IsSyncStatusNew(act.SyncStatus) {
|
||||||
|
createdList, err2 := createSkuAct(ctx, nil, act, actStoreSkuList4Create)
|
||||||
|
updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, createdList, model.SyncFlagNewMask)...)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagNewMask))
|
||||||
|
}
|
||||||
|
} else if model.IsSyncStatusUpdate(act.SyncStatus) {
|
||||||
|
if len(actStoreSkuList4Create) > 0 {
|
||||||
|
addedList, err2 := createSkuAct(ctx, nil, act, actStoreSkuList4Create)
|
||||||
|
updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, addedList, model.SyncFlagNewMask)...)
|
||||||
|
if err = err2; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(actStoreSkuList4Delete) > 0 {
|
||||||
|
deletedList, err2 := cancelSkuAct(ctx, nil, act, actStoreSkuList4Delete)
|
||||||
|
updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, deletedList, model.SyncFlagDeletedMask)...)
|
||||||
|
if err = err2; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}()
|
||||||
|
db := dao.GetDB()
|
||||||
|
_, err2 := dao.BatchUpdateActEntity(db, model.IsSyncStatusDelete(act.SyncStatus), updateItems)
|
||||||
|
if err == nil {
|
||||||
|
err = err2
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) GetActAmple(ctx *jxcontext.Context, vendorStoreID, vendorOrgCode string) (ample int, err error) {
|
||||||
|
for _, v := range mtwmapi.ActTypeList {
|
||||||
|
//1表示进行中
|
||||||
|
if actList, err := getAPI(vendorOrgCode, 0, vendorStoreID).GetByAppPoiCodeAndType(vendorOrgCode, 1, v); err == nil {
|
||||||
|
ample += len(actList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ample, err
|
||||||
|
}
|
||||||
117
business/partner/purchase/tao_vegetable/callback.go
Normal file
117
business/partner/purchase/tao_vegetable/callback.go
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/netprinter"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 美团回调接口
|
||||||
|
func OnCallbackMsg(msg *mtwmapi.CallbackMsg, msgType string) (response *mtwmapi.CallbackResponse) {
|
||||||
|
// 获取平台门店id
|
||||||
|
//_, err := dao.GetStoreDetailByVendorStoreID(dao.GetDB(), GetVendorStoreIDFromMsg(msg), model.VendorIDMTWM, GetVendorAppIdFromMsg(msg))
|
||||||
|
//if err != nil && strings.Contains(err.Error(), "no row found") {
|
||||||
|
// forwardOrderToGy(msg, msgType)
|
||||||
|
// return mtwmapi.SuccessResponse
|
||||||
|
//}
|
||||||
|
if CurPurchaseHandler != nil {
|
||||||
|
if msg.Cmd == mtwmapi.MsgTypeStoreStatusChanged || msg.Cmd == mtwmapi.MsgTypeStoreAuditStatusChanged {
|
||||||
|
response = CurPurchaseHandler.onStoreStatusChanged(msg)
|
||||||
|
} else if msg.Cmd == mtwmapi.MsgTypePrivateNumberDowngrade {
|
||||||
|
response = CurPurchaseHandler.onNumberDowngrade(msg)
|
||||||
|
} else if msg.Cmd == mtwmapi.MsgTypeStoreBind {
|
||||||
|
// 门店授权发生变化 17,失去授权
|
||||||
|
vendorStoreID := msg.FormData.Get("app_poi_code")
|
||||||
|
storeDetail, _ := dao.GetStoreDetailByVendorStoreID(dao.GetDB(), vendorStoreID, model.VendorIDMTWM, "")
|
||||||
|
_, err := netprinter.PrintStoreStatus(jxcontext.AdminCtx, storeDetail, model.VendorIDMTWM, -9)
|
||||||
|
response = mtwmapi.Err2CallbackResponse(err, "")
|
||||||
|
} else {
|
||||||
|
if orderID := GetOrderIDFromMsg(msg); orderID != "" {
|
||||||
|
jxutils.CallMsgHandler(func() {
|
||||||
|
switch msg.Cmd {
|
||||||
|
case mtwmapi.MsgTypeWaybillStatus:
|
||||||
|
response = CurPurchaseHandler.onWaybillMsg(msg)
|
||||||
|
default:
|
||||||
|
response = CurPurchaseHandler.onOrderMsg(msg)
|
||||||
|
}
|
||||||
|
}, jxutils.ComposeUniversalOrderID(orderID, model.VendorIDMTWM))
|
||||||
|
}
|
||||||
|
/*if msg.Cmd == mtwmapi.MsgTypeOrderRefund || msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund {
|
||||||
|
utils.CallFuncAsync(func() {
|
||||||
|
OnFinancialMsg(msg)
|
||||||
|
})
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOrderIDFromMsg(msg *mtwmapi.CallbackMsg) string {
|
||||||
|
return msg.FormData.Get(mtwmapi.KeyOrderID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVendorStoreIDFromMsg(msg *mtwmapi.CallbackMsg) string {
|
||||||
|
return msg.FormData.Get(mtwmapi.KeyAppPoiCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVendorAppIdFromMsg(msg *mtwmapi.CallbackMsg) string {
|
||||||
|
return msg.FormData.Get(mtwmapi.KeyAppID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func forwardOrderToGy(msg *mtwmapi.CallbackMsg, msgType string) {
|
||||||
|
cl := http.Client{}
|
||||||
|
callbackUrl := GetMsgCallBackUrl(msgType, msg.AppID)
|
||||||
|
request, err := http.NewRequest(http.MethodPost, "http://callback-jxgy.jxc4.com/mtwm/"+callbackUrl, strings.NewReader(msg.FormData.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
request.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
|
||||||
|
cl.Do(request)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMsgCallBackUrl(msgType, appId string) string {
|
||||||
|
interfaceUrl := ""
|
||||||
|
switch msgType {
|
||||||
|
case mtwmapi.MsgTypeWaybillStatus:
|
||||||
|
interfaceUrl = "/waybillStatus"
|
||||||
|
case mtwmapi.MsgTypeNewOrder:
|
||||||
|
interfaceUrl = "/newOrder"
|
||||||
|
case mtwmapi.MsgTypeOrderAccepted:
|
||||||
|
interfaceUrl = "/orderAccepted"
|
||||||
|
case mtwmapi.MsgTypeOrderFinished:
|
||||||
|
interfaceUrl = "/orderFinished"
|
||||||
|
case mtwmapi.MsgTypeOrderFinancial:
|
||||||
|
interfaceUrl = "/orderFinancial"
|
||||||
|
case mtwmapi.MsgTypeOrderCanceled:
|
||||||
|
interfaceUrl = "/orderCanceled"
|
||||||
|
case mtwmapi.MsgTypeUserUrgeOrder:
|
||||||
|
interfaceUrl = "/userUrgeOrder"
|
||||||
|
case mtwmapi.MsgTypePrivateNumberDowngrade:
|
||||||
|
interfaceUrl = "/numberDowngrade"
|
||||||
|
case mtwmapi.MsgTypeOrderModified:
|
||||||
|
interfaceUrl = "/orderModified"
|
||||||
|
case mtwmapi.MsgTypeOrderRefund:
|
||||||
|
interfaceUrl = "/orderRefund"
|
||||||
|
case mtwmapi.MsgTypeOrderPartialRefund:
|
||||||
|
interfaceUrl = "/orderPartialRefund"
|
||||||
|
case mtwmapi.MsgTypeOrderFinishedPickup:
|
||||||
|
interfaceUrl = "/orderFinishedPickup"
|
||||||
|
case mtwmapi.MsgTypeStoreStatusChanged:
|
||||||
|
interfaceUrl = "/storeStatusChanged"
|
||||||
|
case mtwmapi.MsgTypeStoreAuditStatusChanged:
|
||||||
|
interfaceUrl = "/storeAuditStatusChanged"
|
||||||
|
case mtwmapi.MsgTypeSkuDelete:
|
||||||
|
interfaceUrl = "/skuDelete"
|
||||||
|
case mtwmapi.MsgTypeStoreBind:
|
||||||
|
interfaceUrl = "/storeBind"
|
||||||
|
default:
|
||||||
|
globals.SugarLogger.Errorf("美团超市[app_id :=%s ,callbackUrl := %s ]回调推送到果园错误,回调地址不正确", appId, msgType)
|
||||||
|
}
|
||||||
|
return interfaceUrl
|
||||||
|
}
|
||||||
245
business/partner/purchase/tao_vegetable/financial.go
Normal file
245
business/partner/purchase/tao_vegetable/financial.go
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"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/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PublicWelfareDonation = 1 // 美团公益捐款金额现阶段是每单一分钱
|
||||||
|
)
|
||||||
|
|
||||||
|
// 存储美团退款订单结账信息
|
||||||
|
func OnFinancialMsg(msg *mtwmapi.CallbackMsg) (err error) {
|
||||||
|
if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { // 部分退款处理
|
||||||
|
orderData := msg.FormData
|
||||||
|
if orderData.Get("notify_type") == mtwmapi.NotifyTypeSuccess {
|
||||||
|
err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(CurPurchaseHandler.AfsOrderDetail2Financial(orderData))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if msg.Cmd == mtwmapi.MsgTypeOrderRefund { // todo 全额退款处理
|
||||||
|
orderData := msg.FormData
|
||||||
|
if orderData.Get("notify_type") == mtwmapi.NotifyTypeSuccess {
|
||||||
|
afsOrderID := orderData.Get("order_id")
|
||||||
|
orderFinancial, err := partner.CurOrderManager.LoadOrderFinancial(afsOrderID, model.VendorIDMTWM)
|
||||||
|
if err == nil {
|
||||||
|
err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(CurPurchaseHandler.OrderFinancialDetail2Refund(orderFinancial, orderData))
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Warnf("mtwm OnFinancialMsg, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrderFinancial", afsOrderID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) OrderFinancialDetail2Refund(orderFinancial *model.OrderFinancial, orderData url.Values) (afsOrder *model.AfsOrder) {
|
||||||
|
afsOrder = &model.AfsOrder{
|
||||||
|
VendorID: model.VendorIDMTWM,
|
||||||
|
AfsOrderID: orderData.Get("refund_id"),
|
||||||
|
VendorOrderID: orderData.Get("order_id"),
|
||||||
|
AfsCreatedAt: utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))),
|
||||||
|
// BoxMoney: orderFinancial.BoxMoney,
|
||||||
|
// SkuBoxMoney: orderFinancial.SkuBoxMoney, // 美团的餐盒费已经拆到单条SKU里面去了,退款时直接计算用户支付sku金额就好了
|
||||||
|
FreightUserMoney: orderFinancial.FreightMoney,
|
||||||
|
SkuUserMoney: orderFinancial.ActualPayMoney - orderFinancial.FreightMoney,
|
||||||
|
PmSubsidyMoney: orderFinancial.PmSubsidyMoney,
|
||||||
|
}
|
||||||
|
order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID)
|
||||||
|
if err == nil {
|
||||||
|
afsOrder.JxStoreID = order.JxStoreID
|
||||||
|
afsOrder.VendorStoreID = order.VendorStoreID
|
||||||
|
afsOrder.StoreID = order.StoreID
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Warnf("mtwm AfsOrderDetail2Financial, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrder", afsOrder.VendorOrderID)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
for _, sku := range orderFinancial.Skus {
|
||||||
|
orderSkuFinancial := &model.OrderSkuFinancial{
|
||||||
|
VendorID: sku.VendorID,
|
||||||
|
VendorOrderID: sku.VendorOrderID,
|
||||||
|
// OrderFinancialID: sku.VendorOrderID,
|
||||||
|
// ConfirmTime: afsOrder.AfsCreateAt,
|
||||||
|
VendorStoreID: afsOrder.VendorStoreID,
|
||||||
|
StoreID: afsOrder.StoreID,
|
||||||
|
JxStoreID: afsOrder.JxStoreID,
|
||||||
|
VendorSkuID: sku.VendorSkuID,
|
||||||
|
SkuID: sku.SkuID,
|
||||||
|
PromotionType: sku.PromotionType,
|
||||||
|
Name: sku.Name,
|
||||||
|
ShopPrice: sku.ShopPrice,
|
||||||
|
SalePrice: sku.SalePrice,
|
||||||
|
Count: sku.Count,
|
||||||
|
UserMoney: sku.UserMoney,
|
||||||
|
PmSubsidyMoney: sku.PmSubsidyMoney,
|
||||||
|
IsAfsOrder: 1,
|
||||||
|
}
|
||||||
|
afsOrder.Skus = append(afsOrder.Skus, orderSkuFinancial)
|
||||||
|
}
|
||||||
|
return afsOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData url.Values) (afsOrder *model.AfsOrder) {
|
||||||
|
afsOrder = &model.AfsOrder{
|
||||||
|
VendorID: model.VendorIDMTWM,
|
||||||
|
AfsOrderID: orderData.Get("order_id"),
|
||||||
|
VendorOrderID: orderData.Get("order_id"),
|
||||||
|
AfsCreatedAt: utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))),
|
||||||
|
RefundMoney: jxutils.StandardPrice2Int(utils.Str2Float64(orderData.Get("money"))),
|
||||||
|
}
|
||||||
|
// if orderData.Get("timestamp") != "" {
|
||||||
|
// afsOrder.AfsCreateAt = utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp")))
|
||||||
|
// } else {
|
||||||
|
// afsOrder.AfsCreateAt = time.Now()
|
||||||
|
// }
|
||||||
|
order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID)
|
||||||
|
if err == nil {
|
||||||
|
afsOrder.JxStoreID = order.JxStoreID
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Warnf("mtwm AfsOrderDetail2Financial, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrder", afsOrder.VendorOrderID)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
food := orderData.Get("food")
|
||||||
|
var refundDetail []map[string]interface{}
|
||||||
|
utils.UnmarshalUseNumber([]byte(food), &refundDetail)
|
||||||
|
for _, xMap := range refundDetail {
|
||||||
|
orderSkuFinancial := &model.OrderSkuFinancial{
|
||||||
|
VendorID: model.VendorIDMTWM,
|
||||||
|
AfsOrderID: afsOrder.AfsOrderID,
|
||||||
|
VendorOrderID: afsOrder.VendorOrderID,
|
||||||
|
// ConfirmTime: afsOrder.AfsCreateAt,
|
||||||
|
VendorSkuID: utils.Interface2String(xMap["app_food_code"]),
|
||||||
|
SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(xMap["sku_id"]), 0)),
|
||||||
|
Name: utils.Interface2String(xMap["food_name"]),
|
||||||
|
UserMoney: jxutils.StandardPrice2Int(utils.MustInterface2Float64(xMap["refund_price"]))*utils.MustInterface2Int64(xMap["count"]) + jxutils.StandardPrice2Int(utils.MustInterface2Float64(xMap["box_price"]))*int64(utils.MustInterface2Float64(xMap["box_num"])),
|
||||||
|
IsAfsOrder: 1,
|
||||||
|
}
|
||||||
|
afsOrder.Skus = append(afsOrder.Skus, orderSkuFinancial)
|
||||||
|
afsOrder.SkuUserMoney += orderSkuFinancial.UserMoney
|
||||||
|
// afsOrder.PmSubsidyMoney += orderSkuFinancial.PmSubsidyMoney // 美团只给了一个扣款金额,很尴尬、、
|
||||||
|
}
|
||||||
|
afsOrder.PmSubsidyMoney += afsOrder.RefundMoney - afsOrder.SkuUserMoney
|
||||||
|
if len(refundDetail) <= 0 {
|
||||||
|
globals.SugarLogger.Warnf("mtwm AfsOrderDetail2Financial, orderID:%s have no refund_detail", afsOrder.VendorOrderID)
|
||||||
|
}
|
||||||
|
return afsOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
// 存储美团正向订单结账信息
|
||||||
|
func (p *PurchaseHandler) OnOrderDetail(result map[string]interface{}, operation string) (err error) {
|
||||||
|
err = partner.CurOrderManager.SaveOrderFinancialInfo(p.OrderDetail2Financial(result), operation)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) OrderDetail2Financial(result map[string]interface{}) (orderFinancial *model.OrderFinancial) {
|
||||||
|
orderFinancial = &model.OrderFinancial{
|
||||||
|
VendorID: model.VendorIDMTWM,
|
||||||
|
VendorOrderID: utils.Int64ToStr(utils.MustInterface2Int64(result["order_id"])),
|
||||||
|
}
|
||||||
|
// orderFinancial.DeliveryConfirmTime = utils.Str2TimeWithDefault(utils.Interface2String(result["order_completed_time"]), utils.DefaultTimeValue)
|
||||||
|
order, err := partner.CurOrderManager.LoadOrder(orderFinancial.VendorOrderID, orderFinancial.VendorID)
|
||||||
|
jxStoreID := 0
|
||||||
|
if err == nil {
|
||||||
|
jxStoreID = order.JxStoreID
|
||||||
|
if order.Skus != nil {
|
||||||
|
for _, x := range order.Skus {
|
||||||
|
orderFinancial.ShopPriceMoney += x.ShopPrice * int64(x.Count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
if result["package_bag_money"] != nil {
|
||||||
|
orderFinancial.BoxMoney = utils.MustInterface2Int64(result["package_bag_money"])
|
||||||
|
}
|
||||||
|
detail := result["detail"]
|
||||||
|
if detail != nil {
|
||||||
|
var data []map[string]interface{}
|
||||||
|
utils.UnmarshalUseNumber([]byte(utils.Interface2String(detail)), &data)
|
||||||
|
for _, x := range data {
|
||||||
|
orderSkuFinancial := &model.OrderSkuFinancial{
|
||||||
|
VendorID: orderFinancial.VendorID,
|
||||||
|
VendorOrderID: orderFinancial.VendorOrderID,
|
||||||
|
// OrderFinancialID: orderFinancial.VendorOrderID,
|
||||||
|
// ConfirmTime: utils.Str2TimeWithDefault(utils.Interface2String(result["ctime"]), utils.DefaultTimeValue),
|
||||||
|
VendorStoreID: result["app_poi_code"].(string),
|
||||||
|
StoreID: 0,
|
||||||
|
JxStoreID: jxStoreID,
|
||||||
|
VendorSkuID: utils.Interface2String(x["sku_id"]),
|
||||||
|
SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(x["sku_id"]), 0)),
|
||||||
|
Name: utils.Interface2String(x["food_name"]),
|
||||||
|
SalePrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["price"])),
|
||||||
|
Count: int(utils.MustInterface2Int64(x["quantity"])),
|
||||||
|
SkuBoxMoney: jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["box_price"])) * jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["box_num"])),
|
||||||
|
IsAfsOrder: 0,
|
||||||
|
}
|
||||||
|
orderFinancial.Skus = append(orderFinancial.Skus, orderSkuFinancial)
|
||||||
|
orderFinancial.SalePriceMoney += orderSkuFinancial.SalePrice * int64(orderSkuFinancial.Count)
|
||||||
|
orderFinancial.SkuBoxMoney += orderSkuFinancial.SkuBoxMoney
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Warnf("mtwm OrderDetail2Financial, orderID:%s have no detail", orderFinancial.VendorOrderID)
|
||||||
|
}
|
||||||
|
extras := result["extras"]
|
||||||
|
if extras != nil {
|
||||||
|
var data []map[string]interface{}
|
||||||
|
utils.UnmarshalUseNumber([]byte(utils.Interface2String(extras)), &data)
|
||||||
|
for _, x := range data {
|
||||||
|
if x["rider_fee"] == nil {
|
||||||
|
activity := &model.OrderDiscountFinancial{
|
||||||
|
VendorID: orderFinancial.VendorID,
|
||||||
|
VendorOrderID: orderFinancial.VendorOrderID,
|
||||||
|
// ActivityName: utils.Interface2String(x["remark"]),
|
||||||
|
// ActivityMoney: jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["reduce_fee"])),
|
||||||
|
// VendorActivityID: utils.Int64ToStr(utils.MustInterface2Int64(x["act_detail_id"])),
|
||||||
|
}
|
||||||
|
if x["act_detail_id"] != nil { // 容错处理
|
||||||
|
activity.VendorActivityID = utils.Int64ToStr(utils.MustInterface2Int64(x["act_detail_id"]))
|
||||||
|
orderFinancial.Discounts = append(orderFinancial.Discounts, activity)
|
||||||
|
}
|
||||||
|
// 通过活动Id去取,京西活动补贴
|
||||||
|
// orderFinancial.JxSubsidyMoney +=
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
poiReceiveDetail := result["poi_receive_detail"]
|
||||||
|
if poiReceiveDetail != nil {
|
||||||
|
var data map[string]interface{}
|
||||||
|
utils.UnmarshalUseNumber([]byte(utils.Interface2String(poiReceiveDetail)), &data)
|
||||||
|
orderFinancial.ReceivableFreight = utils.MustInterface2Int64(data["logisticsFee"])
|
||||||
|
orderFinancial.FreightMoney = utils.MustInterface2Int64(data["logisticsFee"])
|
||||||
|
orderFinancial.ActualPayMoney = utils.MustInterface2Int64(data["onlinePayment"])
|
||||||
|
orderFinancial.PmMoney = utils.MustInterface2Int64(data["foodShareFeeChargeByPoi"])
|
||||||
|
orderFinancial.ShopMoney = utils.MustInterface2Int64(data["wmPoiReceiveCent"])
|
||||||
|
for _, x := range data["actOrderChargeByMt"].([]interface{}) {
|
||||||
|
orderFinancial.TotalDiscountMoney += utils.MustInterface2Int64(x.(map[string]interface{})["moneyCent"])
|
||||||
|
orderFinancial.PmSubsidyMoney += utils.MustInterface2Int64(x.(map[string]interface{})["moneyCent"])
|
||||||
|
}
|
||||||
|
for _, x := range data["actOrderChargeByPoi"].([]interface{}) {
|
||||||
|
orderFinancial.TotalDiscountMoney += utils.MustInterface2Int64(x.(map[string]interface{})["moneyCent"])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Warnf("mtwm OrderDetail2Financial, orderID:%s have no poi_receive_detail", orderFinancial.VendorOrderID)
|
||||||
|
}
|
||||||
|
if utils.MustInterface2Int64(result["is_third_shipping"]) == SelfDeliveryCarrierNo { // is_third_shipping int 是否是第三方配送平台配送,0表否,1表是)
|
||||||
|
orderFinancial.SelfDeliveryDiscountMoney = orderFinancial.ReceivableFreight
|
||||||
|
orderFinancial.DistanceFreightMoney = 0
|
||||||
|
// 通过本地数据库去取是否转美团/达达,并计算运费
|
||||||
|
// wayBill, err := partner.CurOrderManager.LoadWaybill(orderFinancial.VendorOrderID, orderFinancial.VendorID)
|
||||||
|
// if err == nil {
|
||||||
|
// orderFinancial.JxFreightMoney = wayBill.DesiredFee
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
// // 美团订单单独处理部分,美团正向订单接口推送时总结算金额没有计算公益捐款一分钱,是否在这里直接提前扣除?
|
||||||
|
// // 3/18之后的订单一直都不显示公益捐款金额,而且结算现在结算到了3/18之后的订单,没有的已经不计算了,先注释
|
||||||
|
// // 2019-04-03 10.52 询问赵mf, 此计划是必须参加的,而且是长期的,每单固定扣除一分钱
|
||||||
|
orderFinancial.DonationMoney = PublicWelfareDonation
|
||||||
|
// 不应该对第三方结账金额做更改,就算有异常,也要保留异常,知道问题出在哪里
|
||||||
|
// orderFinancial.ShopMoney -= PublicWelfareDonation
|
||||||
|
return orderFinancial
|
||||||
|
}
|
||||||
63
business/partner/purchase/tao_vegetable/financial_test.go
Normal file
63
business/partner/purchase/tao_vegetable/financial_test.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOnFinancialMsg(t *testing.T) {
|
||||||
|
msg := &mtwmapi.CallbackMsg{
|
||||||
|
Cmd: "orderRefund",
|
||||||
|
FormData: url.Values{},
|
||||||
|
}
|
||||||
|
msg.FormData.Set("timestamp", utils.Int64ToStr(time.Now().Unix()))
|
||||||
|
msg.FormData.Set("order_id", "33762863167364867")
|
||||||
|
msg.FormData.Set("notify_type", "agree")
|
||||||
|
msg.FormData.Set("money", "23.56")
|
||||||
|
food := []map[string]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"app_food_code": "123",
|
||||||
|
"food_name": "商品1",
|
||||||
|
"sku_id": "123",
|
||||||
|
"refund_price": 3.14,
|
||||||
|
"count": 2,
|
||||||
|
"box_num": 1,
|
||||||
|
"box_price": 1,
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"app_food_code": "124",
|
||||||
|
"food_name": "商品2",
|
||||||
|
"sku_id": "124",
|
||||||
|
"refund_price": 3.15,
|
||||||
|
"count": 2,
|
||||||
|
"box_num": 1,
|
||||||
|
"box_price": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
msg.FormData.Set("food", string(utils.MustMarshal(food)))
|
||||||
|
res := CurPurchaseHandler.onAfsOrderMsg(msg)
|
||||||
|
fmt.Println(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOnOrderDetail(t *testing.T) {
|
||||||
|
result := map[string]interface{}{
|
||||||
|
"app_order_code": "", "app_poi_code": "2828472", "avg_send_time": 2410, "backup_recipient_phone": "[\"13164714130_7645\"]", "caution": " 【如遇缺货】: 缺货时电话与我沟通 收餐人隐私号 13049813276_5307,手机号 139****5027", "city_id": 440300, "ctime": 1555036346, "day_seq": 1, "delivery_time": 0, "detail": "[{\"app_food_code\":\"27262\",\"box_num\":0,\"box_price\":0,\"cart_id\":0,\"food_discount\":1,\"food_name\":\"红管鱿鱼约250g/份\",\"food_property\":\"\",\"price\":23.54,\"quantity\":1,\"sku_id\":\"27262\",\"spec\":\"250g\",\"unit\":\"份\"},{\"app_food_code\":\"24987\",\"box_num\":0,\"box_price\":0,\"cart_id\":0,\"food_discount\":1,\"food_name\":\"带皮猪梅花肉约250g/份\",\"food_property\":\"\",\"price\":15.84,\"quantity\":1,\"sku_id\":\"24987\",\"spec\":\"250g\",\"unit\":\"份\"},{\"app_food_code\":\"27179\",\"box_num\":0,\"box_price\":0,\"cart_id\":0,\"food_discount\":1,\"food_name\":\"[畅销]龙骨约250g/份\",\"food_property\":\"\",\"price\":18.59,\"quantity\":1,\"sku_id\":\"27179\",\"spec\":\"250g\",\"unit\":\"份\"}]", "dinners_number": 0, "expect_deliver_time": 0, "extras": "[{\"act_detail_id\":664795195,\"mt_charge\":0,\"poi_charge\":5,\"reduce_fee\":5,\"remark\":\"满46.0元减5.0元\",\"type\":2},{\"act_detail_id\":665051798,\"mt_charge\":0,\"poi_charge\":4,\"reduce_fee\":4,\"remark\":\"减配送费4.0元\",\"type\":25},{\"act_detail_id\":274839715,\"mt_charge\":0.5,\"poi_charge\":0,\"reduce_fee\":0.5,\"remark\":\"用户使用了支付红包减0.5元\",\"type\":9},{\"mt_charge\":0,\"poi_charge\":0,\"reduce_fee\":0,\"remark\":\"送30元商家代金券\",\"type\":100},{}]", "has_invoiced": 0, "invoice_title": "", "is_favorites": false, "is_poi_first_order": true, "is_pre": 0, "is_third_shipping": 0, "latitude": 22.530194, "logistics_code": "1001", "longitude": 114.08372, "order_id": 28284722536001020, "order_send_time": 1555036356, "original_price": 63.97, "package_bag_money": 0, "pay_type": 2, "pick_type": 0, "poi_receive_detail": "{\"actOrderChargeByMt\":[{\"comment\":\"活动款\",\"feeTypeDesc\":\"活动款\",\"feeTypeId\":10019,\"moneyCent\":50}],\"actOrderChargeByPoi\":[{\"comment\":\"满46.0元减5.0元\",\"feeTypeDesc\":\"活动款\",\"feeTypeId\":10019,\"moneyCent\":500},{\"comment\":\"减配送费4.0元\",\"feeTypeDesc\":\"活动款\",\"feeTypeId\":10019,\"moneyCent\":400}],\"foodShareFeeChargeByPoi\":490,\"logisticsFee\":600,\"onlinePayment\":5447,\"wmPoiReceiveCent\":4406}", "recipient_address": "汇港名苑 (南2区1005)@#广东省深圳市福田区滨河大道滨河大道3119号汇港名苑", "recipient_name": "颜(女士)", "recipient_phone": "13049813276_5307", "remark": "", "result": "ok", "shipper_phone": "", "shipping_fee": 6, "shipping_type": 0, "source_id": 3, "status": 2, "taxpayer_id": "", "total": 54.47, "utime": 1555036346, "wm_order_id_view": 28284722536001020, "wm_poi_address": "深圳市福田区南园街道南华社区滨河路2037号下小庙南区70栋101号滨河街市场", "wm_poi_id": 2828472, "wm_poi_name": "京西菜市(华强南店)", "wm_poi_phone": "13724313878",
|
||||||
|
}
|
||||||
|
err := new(PurchaseHandler).OnOrderDetail(result, partner.CreatedPeration)
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestName(t *testing.T) {
|
||||||
|
store, err := dao.GetStoreDetailByVendorStoreID(dao.GetDB(), "1", model.VendorIDMTWM, "1")
|
||||||
|
fmt.Println(store)
|
||||||
|
fmt.Println(err)
|
||||||
|
|
||||||
|
}
|
||||||
255
business/partner/purchase/tao_vegetable/mtwm.go
Normal file
255
business/partner/purchase/tao_vegetable/mtwm.go
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
|
||||||
|
"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/partner"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner/putils"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
CurPurchaseHandler *PurchaseHandler
|
||||||
|
)
|
||||||
|
|
||||||
|
type PurchaseHandler struct {
|
||||||
|
partner.BasePurchasePlatform
|
||||||
|
putils.DefSingleStorePlatform
|
||||||
|
|
||||||
|
storeIDs []string
|
||||||
|
locker sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if api.MtwmAPI != nil || api.Mtwm2API != nil {
|
||||||
|
CurPurchaseHandler = New()
|
||||||
|
partner.RegisterPurchasePlatform(CurPurchaseHandler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() (obj *PurchaseHandler) {
|
||||||
|
obj = new(PurchaseHandler)
|
||||||
|
obj.ISingleStoreStoreSkuHandler = obj
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) GetVendorID() int {
|
||||||
|
return model.VendorIDTaoVegetable
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) {
|
||||||
|
cats, err := api.MtwmAPI.RetailGetSpTagIds()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
vendorCatMapList := make([]map[string]*model.SkuVendorCategory, 3)
|
||||||
|
manID := 10000
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
vendorCatMapList[i] = make(map[string]*model.SkuVendorCategory)
|
||||||
|
for _, v := range cats {
|
||||||
|
if v.Level == 3 {
|
||||||
|
namePathList := strings.Split(strings.Trim(v.NamePath, ","), ",")
|
||||||
|
if len(namePathList) != 3 {
|
||||||
|
panic(fmt.Sprintf("%s没有三级结构", v.NamePath))
|
||||||
|
}
|
||||||
|
name := namePathList[i]
|
||||||
|
if _, ok := vendorCatMapList[i][name]; !ok {
|
||||||
|
cat := &model.SkuVendorCategory{
|
||||||
|
VendorID: model.VendorIDTaoVegetable,
|
||||||
|
Name: name, //utils.Interface2String(v["name"]),
|
||||||
|
Level: i + 1, //int(utils.MustInterface2Int64(v["level"])),
|
||||||
|
}
|
||||||
|
vendorCats = append(vendorCats, cat)
|
||||||
|
vendorCatMapList[i][name] = cat
|
||||||
|
if i == 2 {
|
||||||
|
cat.IsLeaf = 1
|
||||||
|
cat.VendorCategoryID = utils.Int64ToStr(v.ID)
|
||||||
|
} else {
|
||||||
|
cat.VendorCategoryID = utils.Int2Str(manID) // 非叶子结点编码没有实际使用
|
||||||
|
manID++
|
||||||
|
}
|
||||||
|
if i > 0 {
|
||||||
|
cat.ParentID = vendorCatMapList[i-1][namePathList[i-1]].VendorCategoryID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vendorCats, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func rangeMtwm2JX(areaStr string) string {
|
||||||
|
var area []interface{}
|
||||||
|
if err := utils.UnmarshalUseNumber([]byte(areaStr), &area); err == nil {
|
||||||
|
if len(area) > 0 {
|
||||||
|
coordList := make([]string, len(area))
|
||||||
|
for k, v := range area {
|
||||||
|
vv := v.(map[string]interface{})
|
||||||
|
coordList[k] = fmt.Sprintf("%.6f,%.6f", jxutils.IntCoordinate2Standard(int(utils.ForceInterface2Int64(vv["x"]))), jxutils.IntCoordinate2Standard(int(utils.ForceInterface2Int64(vv["y"]))))
|
||||||
|
}
|
||||||
|
return strings.Join(coordList, ";")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func openTimeMtwm2JX(vendorOpenTime string) (opTimeList []int16) {
|
||||||
|
timePairs := strings.Split(vendorOpenTime, ",")
|
||||||
|
for _, v := range timePairs {
|
||||||
|
times := strings.Split(v, "-")
|
||||||
|
if len(times) >= 2 {
|
||||||
|
opTimeList = append(opTimeList, jxutils.StrTime2JxOperationTime(times[0]+":00", 700), jxutils.StrTime2JxOperationTime(times[1]+":00", 2000))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return opTimeList
|
||||||
|
}
|
||||||
|
|
||||||
|
func openTimeJX2Mtwm(opTimeList []int16) string {
|
||||||
|
timesLen := len(opTimeList) / 2 * 2
|
||||||
|
var strPairs []string
|
||||||
|
for i := 0; i < timesLen; i += 2 {
|
||||||
|
if opTimeList[i] != 0 {
|
||||||
|
strPairs = append(strPairs, jxutils.JxOperationTime2StrTime(opTimeList[i])+"-"+jxutils.JxOperationTime2StrTime(opTimeList[i+1]))
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(strPairs, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
func bizStatusMtwm2JX(openLevel, online int) int {
|
||||||
|
if online != mtwmapi.PoiStatusOnline {
|
||||||
|
return model.StoreStatusDisabled
|
||||||
|
} else {
|
||||||
|
if openLevel == mtwmapi.PoiOpenLevelHaveRest {
|
||||||
|
return model.StoreStatusClosed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return model.StoreStatusOpened
|
||||||
|
}
|
||||||
|
|
||||||
|
func bizStatusJX2Mtwm(status int) (openLevel, online int) {
|
||||||
|
if status == model.StoreStatusDisabled {
|
||||||
|
return mtwmapi.PoiOpenLevelHaveRest, mtwmapi.PoiStatusOnline //mtwmapi.PoiStatusOffline
|
||||||
|
} else if status == model.StoreStatusHaveRest || status == model.StoreStatusClosed {
|
||||||
|
return mtwmapi.PoiOpenLevelHaveRest, mtwmapi.PoiStatusOnline
|
||||||
|
}
|
||||||
|
return mtwmapi.PoiOpenLevelNormal, mtwmapi.PoiStatusOnline
|
||||||
|
}
|
||||||
|
|
||||||
|
func skuStatusJX2Mtwm(status int) int {
|
||||||
|
if status == model.SkuStatusNormal {
|
||||||
|
return mtwmapi.SellStatusOnline
|
||||||
|
}
|
||||||
|
return mtwmapi.SellStatusOffline
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) {
|
||||||
|
poiCode4UploadImg := p.getUploadImgPoiCode()
|
||||||
|
if poiCode4UploadImg == "" {
|
||||||
|
return "", fmt.Errorf("找不到一个美团门店来上传图片")
|
||||||
|
}
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
if imgType > model.ImgTypeLocal {
|
||||||
|
if imgData != nil {
|
||||||
|
imgHint, err = api.MtwmAPI.ImageUpload(poiCode4UploadImg, imgName, imgData)
|
||||||
|
} else {
|
||||||
|
imgHint, err = api.MtwmAPI.ImageUploadByURL(poiCode4UploadImg, imgName, imgURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
imgHint = utils.GetUpperUUID()
|
||||||
|
}
|
||||||
|
return imgHint, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStoreIDFromList(storeIDs []string) (poiCode string) {
|
||||||
|
if len(storeIDs) > 0 {
|
||||||
|
poiCode = storeIDs[0]
|
||||||
|
}
|
||||||
|
return poiCode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) getUploadImgPoiCode() (poiCode string) {
|
||||||
|
var storeIDs []string
|
||||||
|
p.locker.RLock()
|
||||||
|
storeIDs = p.storeIDs
|
||||||
|
p.locker.RUnlock()
|
||||||
|
if len(storeIDs) > 0 {
|
||||||
|
return getStoreIDFromList(storeIDs)
|
||||||
|
}
|
||||||
|
|
||||||
|
p.locker.Lock()
|
||||||
|
storeIDs = p.storeIDs
|
||||||
|
if len(storeIDs) > 0 {
|
||||||
|
p.locker.Unlock()
|
||||||
|
return getStoreIDFromList(storeIDs)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer p.locker.Unlock()
|
||||||
|
storeIDs, err := api.MtwmAPI.PoiGetIDs()
|
||||||
|
if err == nil {
|
||||||
|
if len(storeIDs) > 0 {
|
||||||
|
p.storeIDs = storeIDs
|
||||||
|
poiCode = getStoreIDFromList(storeIDs)
|
||||||
|
} else {
|
||||||
|
// p.storeIDs = []string{""}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return poiCode
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAPI(appOrgCode string, storeID int, vendorStoreID string) (apiObj *mtwmapi.API) {
|
||||||
|
if appOrgCode == "" {
|
||||||
|
globals.SugarLogger.Debugf("getAPI appOrgCode is empty")
|
||||||
|
}
|
||||||
|
apiObj = partner.CurAPIManager.GetAPI(model.VendorIDTaoVegetable, appOrgCode).(*mtwmapi.API)
|
||||||
|
if appOrgCode == globals.Mtwm2Code {
|
||||||
|
var storeDetail *dao.StoreDetail
|
||||||
|
if storeID != 0 {
|
||||||
|
storeDetail, _ = dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDTaoVegetable, appOrgCode)
|
||||||
|
} else if vendorStoreID != "" {
|
||||||
|
storeDetail, _ = dao.GetStoreDetailByVendorStoreID(dao.GetDB(), vendorStoreID, model.VendorIDTaoVegetable, appOrgCode)
|
||||||
|
}
|
||||||
|
if storeDetail != nil {
|
||||||
|
apiObj.SetToken(storeDetail.MtwmToken)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return apiObj
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAPI(appOrgCode string, storeID int, vendorStoreID string) (apiObj *mtwmapi.API) {
|
||||||
|
if appOrgCode == "" {
|
||||||
|
globals.SugarLogger.Debugf("getAPI appOrgCode is empty")
|
||||||
|
}
|
||||||
|
apiObj = partner.CurAPIManager.GetAPI(model.VendorIDTaoVegetable, appOrgCode).(*mtwmapi.API)
|
||||||
|
if appOrgCode == globals.Mtwm2Code {
|
||||||
|
var storeDetail *dao.StoreDetail
|
||||||
|
if storeID != 0 {
|
||||||
|
storeDetail, _ = dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDTaoVegetable, appOrgCode)
|
||||||
|
} else if vendorStoreID != "" {
|
||||||
|
storeDetail, _ = dao.GetStoreDetailByVendorStoreID(dao.GetDB(), vendorStoreID, model.VendorIDTaoVegetable, appOrgCode)
|
||||||
|
}
|
||||||
|
if storeDetail != nil {
|
||||||
|
apiObj.SetToken(storeDetail.MtwmToken)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return apiObj
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAPIWithoutToken(appOrgCode string) (apiObj *mtwmapi.API) {
|
||||||
|
if appOrgCode == "" {
|
||||||
|
globals.SugarLogger.Warnf("getAPI appOrgCode is empty")
|
||||||
|
}
|
||||||
|
return partner.CurAPIManager.GetAPI(model.VendorIDTaoVegetable, appOrgCode).(*mtwmapi.API)
|
||||||
|
}
|
||||||
50
business/partner/purchase/tao_vegetable/mtwm_test.go
Normal file
50
business/partner/purchase/tao_vegetable/mtwm_test.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
_ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals/testinit"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
testShopVendorID = "2523687"
|
||||||
|
testShopID = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
testinit.Init()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取平台分类属性(三级分类标签)
|
||||||
|
func TestGetVendorCategories(t *testing.T) {
|
||||||
|
result, err := new(PurchaseHandler).GetVendorCategories(jxcontext.AdminCtx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
for _, v := range result {
|
||||||
|
data := model.SkuVendorCategory{
|
||||||
|
ModelIDCUL: model.ModelIDCUL{
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
LastOperator: "刘磊",
|
||||||
|
},
|
||||||
|
VendorCategoryID: v.VendorCategoryID,
|
||||||
|
VendorID: v.VendorID,
|
||||||
|
Name: v.Name,
|
||||||
|
IsLeaf: v.IsLeaf,
|
||||||
|
Level: v.Level,
|
||||||
|
ParentID: v.ParentID,
|
||||||
|
}
|
||||||
|
if err := dao.CreateEntity(dao.GetDB(), &data); err != nil {
|
||||||
|
t.Log(utils.Format4Output(err, false))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.Log(utils.Format4Output(result, false))
|
||||||
|
}
|
||||||
872
business/partner/purchase/tao_vegetable/order.go
Normal file
872
business/partner/purchase/tao_vegetable/order.go
Normal file
@@ -0,0 +1,872 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"net/url"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"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/jxutils/tasksch"
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FakeMsgType = "fakeMsgType"
|
||||||
|
|
||||||
|
fakeFinishedPickup = "fake_finished_pickup"
|
||||||
|
fakeUserApplyCancel = "fake_user_apply_cancel"
|
||||||
|
fakeMerchantAgreeApplyCancel = "fake_merchant_agree_apply_cancel"
|
||||||
|
fakeRefuseUserApplyCancel = "fake_refuse_user_apply_cancel"
|
||||||
|
fakeUserUndoApplyCancel = "fake_user_undo_apply_cancel"
|
||||||
|
fakeOrderAdjustFinished = "fake_order_adjust_finished"
|
||||||
|
|
||||||
|
keyVendorOrgCode = "vendorOrgCode"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SelfDeliveryCarrierNo = 1 // 美团配送方式:0-美团专送,1-商家自送
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// pickupOrderDelay = 260 * time.Second
|
||||||
|
// pickupOrderDelay = 1 * time.Second
|
||||||
|
|
||||||
|
// callDeliveryDelay = 10 * time.Minute
|
||||||
|
// callDeliveryDelayGap = 30
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
specPat = regexp.MustCompile(`(\d+)(.+)`)
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
VendorStatus2StatusMap = map[string]int{
|
||||||
|
mtwmapi.OrderStatusUserCommitted: model.OrderStatusUnknown,
|
||||||
|
mtwmapi.OrderStatusNew: model.OrderStatusNew,
|
||||||
|
// mtwmapi.OrderStatusReceived: model.OrderStatusAccepted,
|
||||||
|
// mtwmapi.OrderStatusAccepted: model.OrderStatusFinishedPickup,
|
||||||
|
mtwmapi.OrderStatusAccepted: model.OrderStatusAccepted,
|
||||||
|
|
||||||
|
mtwmapi.OrderStatusDelivering: model.OrderStatusDelivering,
|
||||||
|
mtwmapi.OrderStatusDelivered: model.OrderStatusUnknown, // 以mtwmapi.OrderStatusFinished为结束状态,这个当成一个中间状态(且很少看到这个状态)
|
||||||
|
mtwmapi.OrderStatusFinished: model.OrderStatusFinished,
|
||||||
|
mtwmapi.OrderStatusCanceled: model.OrderStatusCanceled,
|
||||||
|
|
||||||
|
fakeFinishedPickup: model.OrderStatusFinishedPickup,
|
||||||
|
fakeOrderAdjustFinished: model.OrderStatusAdjust,
|
||||||
|
fakeRefuseUserApplyCancel: model.OrderStatusVendorRejectCancel,
|
||||||
|
fakeUserApplyCancel: model.OrderStatusApplyCancel,
|
||||||
|
fakeUserUndoApplyCancel: model.OrderStatusUndoApplyCancel,
|
||||||
|
fakeMerchantAgreeApplyCancel: model.OrderStatusCanceled,
|
||||||
|
}
|
||||||
|
|
||||||
|
skuActTypeMap = map[int]int{
|
||||||
|
mtwmapi.ExtrasPromotionTypeTeJiaCai: 1,
|
||||||
|
mtwmapi.ExtrasPromotionTypeZheKouCai: 1,
|
||||||
|
mtwmapi.ExtrasPromotionTypeSecondHalfPrice: 1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) getStatusFromVendorStatus(vendorStatus string) int {
|
||||||
|
if status, ok := VendorStatus2StatusMap[vendorStatus]; ok {
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
return model.OrderStatusUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) getOrder(vendorOrgCode, vendorOrderID, vendorStoreID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) {
|
||||||
|
result, err := getAPI(vendorOrgCode, 0, vendorStoreID).OrderGetOrderDetail(utils.Str2Int64(vendorOrderID), true)
|
||||||
|
if err == nil {
|
||||||
|
result[keyVendorOrgCode] = vendorOrgCode
|
||||||
|
order = p.Map2Order(result)
|
||||||
|
}
|
||||||
|
return order, result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) getOrderRider(vendorOrgCode, vendorStoreID string, param map[string]interface{}) (err error) {
|
||||||
|
return getAPI(vendorOrgCode, 0, vendorStoreID).OrderStatusAndPsInfo(param)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetOrderRider(vendorOrgCode, vendorStoreID string, param map[string]interface{}) (err error) {
|
||||||
|
return p.getOrderRider(vendorOrgCode, vendorStoreID, param)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID, vendorStoreID string) (order *model.GoodsOrder, err error) {
|
||||||
|
order, _, err = p.getOrder(vendorOrgCode, vendorOrderID, vendorStoreID)
|
||||||
|
return order, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) {
|
||||||
|
if order, _ := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDMTWM); order != nil {
|
||||||
|
status, err = getAPI(vendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderViewStatus(utils.Str2Int64(vendorOrderID))
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
status = p.getStatusFromVendorStatus(utils.Int2Str(status))
|
||||||
|
}
|
||||||
|
return status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
|
||||||
|
result := orderData
|
||||||
|
vendorOrderID := utils.Int64ToStr(utils.MustInterface2Int64(result["order_id"]))
|
||||||
|
// 因为美团外卖不能自动设置商家门店号,且只能通过商家门店号来访问门店,
|
||||||
|
// 为了在后台设置简单一致,把app_poi_code直接当成平台门店号使用(即在后台设置时,平台门店号与商家门店号一样)
|
||||||
|
// 订单中wm_poi_id实际来平台门店号,app_poi_code为商家门店号,这样一来,这两个就相同了
|
||||||
|
|
||||||
|
//_修改为,
|
||||||
|
caution := strings.ReplaceAll(utils.Interface2String(result["caution"]), "_", ",")
|
||||||
|
|
||||||
|
order = &model.GoodsOrder{
|
||||||
|
VendorOrderID: vendorOrderID,
|
||||||
|
// VendorOrderID2: utils.Int64ToStr(utils.MustInterface2Int64(result["wm_order_id_view"])),
|
||||||
|
VendorID: model.VendorIDMTWM,
|
||||||
|
VendorStoreID: result["app_poi_code"].(string),
|
||||||
|
StoreID: 0,
|
||||||
|
// VendorStoreID: utils.Int64ToStr(utils.MustInterface2Int64(result["wm_poi_id"])),
|
||||||
|
// StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["app_poi_code"]), 0)),
|
||||||
|
StoreName: result["wm_poi_name"].(string),
|
||||||
|
ConsigneeName: result["recipient_name"].(string),
|
||||||
|
ConsigneeMobile: jxutils.FormalizeMobile(result["recipient_phone"].(string)),
|
||||||
|
ConsigneeAddress: result["recipient_address"].(string),
|
||||||
|
CoordinateType: model.CoordinateTypeMars,
|
||||||
|
//BuyerComment: utils.TrimBlankChar(utils.Interface2String(result["caution"])),
|
||||||
|
BuyerComment: utils.TrimBlankChar(caution),
|
||||||
|
ExpectedDeliveredTime: getTimeFromTimestamp(utils.Interface2Int64WithDefault(result["delivery_time"], 0)),
|
||||||
|
PickDeadline: utils.DefaultTimeValue,
|
||||||
|
VendorStatus: utils.Int64ToStr(utils.MustInterface2Int64(result["status"])),
|
||||||
|
OrderSeq: int(utils.MustInterface2Int64(result["day_seq"])),
|
||||||
|
StatusTime: getTimeFromTimestamp(utils.MustInterface2Int64(result["ctime"])),
|
||||||
|
OrderCreatedAt: getTimeFromTimestamp(utils.MustInterface2Int64(result["ctime"])),
|
||||||
|
// OrderFinishedAt: getTimeFromTimestamp(utils.MustInterface2Int64(result["order_completed_time"])),
|
||||||
|
OriginalData: string(utils.MustMarshal(result)),
|
||||||
|
ActualPayPrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(result["total"])),
|
||||||
|
BaseFreightMoney: jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["shipping_fee"], 0)),
|
||||||
|
|
||||||
|
InvoiceTitle: utils.Interface2String(result["invoice_title"]),
|
||||||
|
InvoiceTaxerID: utils.Interface2String(result["taxpayer_id"]),
|
||||||
|
InvoiceEmail: jxutils.GetOneEmailFromStr(utils.Interface2String(result["caution"])),
|
||||||
|
|
||||||
|
VendorOrgCode: utils.Interface2String(result[keyVendorOrgCode]),
|
||||||
|
}
|
||||||
|
if result["order_completed_time"] != nil {
|
||||||
|
order.OrderFinishedAt = getTimeFromTimestamp(utils.MustInterface2Int64(result["order_completed_time"]))
|
||||||
|
} else {
|
||||||
|
order.OrderFinishedAt = utils.DefaultTimeValue
|
||||||
|
}
|
||||||
|
pickType := int(utils.Interface2Int64WithDefault(result["pick_type"], 0))
|
||||||
|
if pickType == mtwmapi.OrderPickTypeSelf {
|
||||||
|
order.DeliveryType = model.OrderDeliveryTypeSelfTake
|
||||||
|
} else {
|
||||||
|
logisticsCode := utils.Interface2String(result["logistics_code"])
|
||||||
|
if logisticsCode == mtwmapi.PeiSongTypeSelf || logisticsCode == mtwmapi.PeiSongTypeMTZSPT {
|
||||||
|
order.DeliveryType = model.OrderDeliveryTypeStoreSelf
|
||||||
|
} else {
|
||||||
|
order.DeliveryType = model.OrderDeliveryTypePlatform
|
||||||
|
}
|
||||||
|
}
|
||||||
|
openUID := utils.Interface2Int64WithDefault(result["openUid"], 0)
|
||||||
|
if openUID > 0 {
|
||||||
|
order.VendorUserID = utils.Int64ToStr(openUID)
|
||||||
|
}
|
||||||
|
// 不设置最晚拣货时间,以缺省值为准
|
||||||
|
// if utils.IsTimeZero(order.PickDeadline) && !utils.IsTimeZero(order.StatusTime) {
|
||||||
|
// order.PickDeadline = order.StatusTime.Add(pickupOrderDelay) // 美团外卖要求在5分钟内拣货,不然订单会被取消
|
||||||
|
// }
|
||||||
|
order.Status = p.getStatusFromVendorStatus(order.VendorStatus)
|
||||||
|
if utils.IsTimeZero(order.ExpectedDeliveredTime) {
|
||||||
|
order.BusinessType = model.BusinessTypeImmediate
|
||||||
|
} else {
|
||||||
|
order.BusinessType = model.BusinessTypeDingshida
|
||||||
|
}
|
||||||
|
|
||||||
|
originalLng := utils.MustInterface2Float64(result["longitude"])
|
||||||
|
originalLat := utils.MustInterface2Float64(result["latitude"])
|
||||||
|
order.ConsigneeLng = jxutils.StandardCoordinate2Int(originalLng)
|
||||||
|
order.ConsigneeLat = jxutils.StandardCoordinate2Int(originalLat)
|
||||||
|
|
||||||
|
var detail []map[string]interface{}
|
||||||
|
if err := utils.UnmarshalUseNumber([]byte(result["detail"].(string)), &detail); err != nil {
|
||||||
|
panic(fmt.Sprintf("mtwm Map2Order vendorID:%s failed with error:%v", vendorOrderID, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加需要赠送的东西
|
||||||
|
if result["extras"] != nil {
|
||||||
|
var extraList []*mtwmapi.OrderExtraInfo
|
||||||
|
if err := utils.UnmarshalUseNumber([]byte(result["extras"].(string)), &extraList); err != nil {
|
||||||
|
panic(fmt.Sprintf("mtwm Map2Order vendorID:%s failed with error:%v", vendorOrderID, err))
|
||||||
|
}
|
||||||
|
for _, extra := range extraList {
|
||||||
|
order.DiscountMoney += jxutils.StandardPrice2Int(extra.ReduceFee)
|
||||||
|
if extra.Type == mtwmapi.ExtrasPromotionTypeTaoCanZeng || extra.Type == mtwmapi.ExtrasPromotionTypeManZeng {
|
||||||
|
sku := &model.OrderSku{
|
||||||
|
VendorOrderID: order.VendorOrderID,
|
||||||
|
VendorID: model.VendorIDMTWM,
|
||||||
|
Count: 1,
|
||||||
|
SkuID: 0,
|
||||||
|
VendorSkuID: "",
|
||||||
|
SkuName: extra.Remark,
|
||||||
|
Weight: 0,
|
||||||
|
SalePrice: 0,
|
||||||
|
StoreSubName: utils.Int2Str(extra.Type),
|
||||||
|
}
|
||||||
|
order.Skus = append(order.Skus, sku)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if poiReceiveDetailStr := utils.Interface2String(result["poi_receive_detail"]); poiReceiveDetailStr != "" {
|
||||||
|
var poiReceiveDetail *mtwmapi.PoiReceiveDetailInfo
|
||||||
|
utils.UnmarshalUseNumber([]byte(poiReceiveDetailStr), &poiReceiveDetail)
|
||||||
|
if poiReceiveDetail != nil {
|
||||||
|
order.TotalShopMoney = poiReceiveDetail.WmPoiReceiveCent
|
||||||
|
for _, v := range poiReceiveDetail.ActOrderChargeByMt {
|
||||||
|
order.PmSubsidyMoney += v.MoneyCent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var skuBenefitDetailMap map[string]*mtwmapi.SkuBenefitDetailInfo
|
||||||
|
if skuBenefitDetai := utils.Interface2String(result["sku_benefit_detail"]); skuBenefitDetai != "" {
|
||||||
|
skuBenefitDetailMap = make(map[string]*mtwmapi.SkuBenefitDetailInfo)
|
||||||
|
var skuBenefitDetailList []*mtwmapi.SkuBenefitDetailInfo
|
||||||
|
utils.UnmarshalUseNumber([]byte(skuBenefitDetai), &skuBenefitDetailList)
|
||||||
|
for _, v := range skuBenefitDetailList {
|
||||||
|
skuBenefitDetailMap[v.SkuID] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ignoreSkuMap := make(map[int]int)
|
||||||
|
multiSkuMap := make(map[int]int)
|
||||||
|
for _, product := range detail {
|
||||||
|
skuName := product["food_name"].(string)
|
||||||
|
skuID := utils.Interface2String(product["sku_id"])
|
||||||
|
sku := &model.OrderSku{
|
||||||
|
VendorOrderID: order.VendorOrderID,
|
||||||
|
VendorID: model.VendorIDMTWM,
|
||||||
|
Count: int(utils.MustInterface2Float64(product["quantity"])),
|
||||||
|
SkuID: int(utils.Str2Int64WithDefault(skuID, 0)),
|
||||||
|
VendorSkuID: skuID,
|
||||||
|
SkuName: skuName,
|
||||||
|
Weight: getSkuWeight(product),
|
||||||
|
VendorPrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"])),
|
||||||
|
SalePrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"])),
|
||||||
|
}
|
||||||
|
if product["upc"] != nil && product["upc"].(string) != "" {
|
||||||
|
sku.Upc = product["upc"].(string)
|
||||||
|
}
|
||||||
|
_, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(sku.SkuName)
|
||||||
|
nameWeight := jxutils.FormatSkuWeight(specQuality, specUnit)
|
||||||
|
if nameWeight == 0 {
|
||||||
|
skuName += " " + product["spec"].(string)
|
||||||
|
}
|
||||||
|
if sku.VendorSkuID == "" {
|
||||||
|
if !strings.Contains(product["app_food_code"].(string), "mtcode") {
|
||||||
|
sku.VendorSkuID = product["app_food_code"].(string)
|
||||||
|
} else {
|
||||||
|
sku.VendorSkuID = utils.Int64ToStr(utils.Interface2Int64WithDefault(product["mt_sku_id"], 0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sku.Weight == 0 {
|
||||||
|
sku.Weight = 222 // 如果名字里找不到缺省给半斤左右的一个特别值
|
||||||
|
}
|
||||||
|
if skuBenefitDetailMap != nil && skuBenefitDetailMap[sku.VendorSkuID] != nil && ignoreSkuMap[sku.SkuID] == 0 /* && sku.Count == 1 */ {
|
||||||
|
for _, v := range skuBenefitDetailMap[sku.VendorSkuID].WmAppOrderActDetails {
|
||||||
|
if /*skuActTypeMap[v.Type] == 1 && */ strings.Index(v.Remark, skuName) >= 0 && sku.Count == v.Count {
|
||||||
|
if sku.SalePrice-jxutils.StandardPrice2Int(v.MtCharge+v.PoiCharge) < 0 {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
ignoreSkuMap[sku.SkuID] = 1
|
||||||
|
sku.SalePrice -= jxutils.StandardPrice2Int(v.MtCharge + v.PoiCharge)
|
||||||
|
}
|
||||||
|
sku.StoreSubName = utils.Int2Str(v.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sku.SalePrice < 0 {
|
||||||
|
sku.SalePrice = jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"]))
|
||||||
|
}
|
||||||
|
order.Skus = append(order.Skus, sku)
|
||||||
|
multiSkuMap[sku.SkuID]++
|
||||||
|
}
|
||||||
|
for _, v := range order.Skus {
|
||||||
|
if multiSkuMap[v.SkuID] > 1 && v.SalePrice == v.VendorPrice {
|
||||||
|
v.IsVendorAct = model.YES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 包装袋金额设置
|
||||||
|
store, _ := dao.GetStoreDetail(dao.GetDB(), order.JxStoreID, order.VendorID, order.VendorOrgCode)
|
||||||
|
order.PackagePrice = store.PackageSetting
|
||||||
|
jxutils.RefreshOrderSkuRelated(order)
|
||||||
|
return order
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRefundSkuDetailList(msg *mtwmapi.CallbackMsg, order *model.GoodsOrder) (skuList []*mtwmapi.RefundSkuDetail, err error) {
|
||||||
|
if false {
|
||||||
|
skuList = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").GetRefundSkuDetailFromMsg(msg)
|
||||||
|
} else {
|
||||||
|
refundOrderDetailList, err2 := getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").GetOrderRefundDetail(utils.Str2Int64(GetOrderIDFromMsg(msg)), mtwmapi.RefundTypePart)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
for _, v := range refundOrderDetailList {
|
||||||
|
skuList = append(skuList, v.WmAppRetailForOrderPartRefundList...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skuList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSkuWeight(product map[string]interface{}) (weight int) {
|
||||||
|
if weight = int(utils.Interface2Int64WithDefault(product["weight"], 0)); weight == 0 {
|
||||||
|
searchResult := specPat.FindStringSubmatch(product["spec"].(string))
|
||||||
|
if len(searchResult) == 3 {
|
||||||
|
weight = jxutils.FormatSkuWeight(float32(utils.Str2Float64WithDefault(searchResult[1], 0)), utils.TrimBlankChar(searchResult[2]))
|
||||||
|
}
|
||||||
|
if weight == 0 {
|
||||||
|
_, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(product["food_name"].(string))
|
||||||
|
weight = jxutils.FormatSkuWeight(specQuality, specUnit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return weight
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) onOrderMsg(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) {
|
||||||
|
var err error
|
||||||
|
if c.isAfsMsg(msg) {
|
||||||
|
response = c.OnAfsOrderMsg(msg)
|
||||||
|
return response
|
||||||
|
} else {
|
||||||
|
status := c.callbackMsg2Status(msg)
|
||||||
|
if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if msg.Cmd == mtwmapi.MsgTypeNewOrder {
|
||||||
|
order, orderMap, err2 := c.getOrder(msg.AppID, GetOrderIDFromMsg(msg), GetVendorStoreIDFromMsg(msg))
|
||||||
|
if err = err2; err == nil {
|
||||||
|
err = partner.CurOrderManager.OnOrderNew(order, c.callbackMsg2Status(msg))
|
||||||
|
if err == nil {
|
||||||
|
utils.CallFuncAsync(func() {
|
||||||
|
if msg.Cmd == mtwmapi.MsgTypeNewOrder {
|
||||||
|
c.OnOrderDetail(orderMap, partner.CreatedPeration)
|
||||||
|
} else {
|
||||||
|
c.OnOrderDetail(orderMap, partner.UpdatedPeration)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if status != nil {
|
||||||
|
var order *model.GoodsOrder
|
||||||
|
if order, err = partner.CurOrderManager.LoadOrder(GetOrderIDFromMsg(msg), model.VendorIDMTWM); err == nil {
|
||||||
|
// if order, err = c.GetOrder(msg.AppID, GetOrderIDFromMsg(msg)); err == nil {
|
||||||
|
if status.Status == model.OrderStatusAdjust {
|
||||||
|
skuList, err2 := getRefundSkuDetailList(msg, order)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
var removedSkuList []*model.OrderSku
|
||||||
|
for _, mtwmSku := range skuList {
|
||||||
|
order.ActualPayPrice -= jxutils.StandardPrice2Int(mtwmSku.RefundPrice) * int64(mtwmSku.Count)
|
||||||
|
removedSkuList = append(removedSkuList, &model.OrderSku{
|
||||||
|
SkuID: int(utils.Str2Int64WithDefault(mtwmSku.SkuID, 0)),
|
||||||
|
Count: mtwmSku.Count,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
order = jxutils.RemoveSkuFromOrder(order, removedSkuList)
|
||||||
|
jxutils.RefreshOrderSkuRelated(order)
|
||||||
|
err = partner.CurOrderManager.OnOrderAdjust(order, status)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if status.Status == model.OrderStatusDelivering {
|
||||||
|
// 美团订单即使时在配送状态时,如果之前没有调用过拣货完成,也会对门店指标生成影响,这里强制再调用拣货完成,且忽略错误
|
||||||
|
utils.CallFuncAsync(func() {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").PreparationMealComplete(utils.Str2Int64(status.VendorOrderID))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
err = partner.CurOrderManager.OnOrderStatusChanged(msg.AppID, status)
|
||||||
|
if err == nil && msg.Cmd == mtwmapi.MsgTypeOrderFinished {
|
||||||
|
utils.CallFuncAsync(func() {
|
||||||
|
orderMap, err := getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderGetOrderDetail(utils.Str2Int64(GetOrderIDFromMsg(msg)), true)
|
||||||
|
if err == nil && utils.MustInterface2Int64(orderMap["is_third_shipping"]) == SelfDeliveryCarrierNo {
|
||||||
|
c.OnOrderDetail(orderMap, partner.UpdatedPeration)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mtwmapi.Err2CallbackResponse(err, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) callbackMsg2Status(msg *mtwmapi.CallbackMsg) (orderStatus *model.OrderStatus) {
|
||||||
|
orderID := GetOrderIDFromMsg(msg)
|
||||||
|
vendorStatus := msg.Cmd
|
||||||
|
remark := ""
|
||||||
|
statusTime := utils.Str2Int64(msg.FormData.Get("timestamp"))
|
||||||
|
switch msg.Cmd {
|
||||||
|
case mtwmapi.MsgTypeUserUrgeOrder, mtwmapi.MsgTypeOrderModified, mtwmapi.MsgTypeOrderFinancial:
|
||||||
|
vendorStatus = msg.Cmd
|
||||||
|
case mtwmapi.MsgTypeOrderCanceled:
|
||||||
|
vendorStatus = mtwmapi.OrderStatusCanceled
|
||||||
|
remark = msg.FormData.Get("reason")
|
||||||
|
case FakeMsgType, mtwmapi.MsgTypeNewOrder, mtwmapi.MsgTypeOrderAccepted, mtwmapi.MsgTypeOrderFinished:
|
||||||
|
vendorStatus = msg.FormData.Get("status")
|
||||||
|
statusTime = utils.Str2Int64(msg.FormData.Get("utime"))
|
||||||
|
case mtwmapi.MsgTypeOrderRefund, mtwmapi.MsgTypeOrderPartialRefund: // 订单退款,部分退款
|
||||||
|
notifyType := msg.FormData.Get("notify_type")
|
||||||
|
vendorStatus = msg.Cmd + "-" + notifyType
|
||||||
|
if true { // 已经提前判断了,到这里的都是售中
|
||||||
|
remark = msg.FormData.Get("reason")
|
||||||
|
if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { // 部分退款
|
||||||
|
if notifyType == mtwmapi.NotifyTypePartyApply {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
//if order, _ := partner.CurOrderManager.LoadOrder(orderID, model.VendorIDMTWM); order != nil {
|
||||||
|
// getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderRefundAgree(utils.Str2Int64(orderID), "自动确认退款")
|
||||||
|
//}
|
||||||
|
// goods, err := dao.GetSimpleOrder(dao.GetDB(), orderID)
|
||||||
|
// if err == nil {
|
||||||
|
// if goods.Status < model.OrderStatusDelivering {
|
||||||
|
// } else {
|
||||||
|
// api.MtwmAPI.OrderRefundReject(utils.Str2Int64(orderID), "商品配送中,请联系门店。") // todo 京东与饿百都没有售前用户提出订单调整的,自动拒绝调整单
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
} else if notifyType == mtwmapi.NotifyTypeSuccess {
|
||||||
|
vendorStatus = fakeOrderAdjustFinished
|
||||||
|
}
|
||||||
|
} else if msg.Cmd == mtwmapi.MsgTypeOrderRefund {
|
||||||
|
if notifyType == mtwmapi.NotifyTypeApply {
|
||||||
|
vendorStatus = fakeUserApplyCancel
|
||||||
|
} else if notifyType == mtwmapi.NotifyTypeCancelRefund || notifyType == mtwmapi.NotifyTypeCancelRefundComplaint {
|
||||||
|
vendorStatus = fakeUserUndoApplyCancel
|
||||||
|
} else if notifyType == mtwmapi.NotifyTypeReject {
|
||||||
|
vendorStatus = fakeRefuseUserApplyCancel
|
||||||
|
} else if notifyType == mtwmapi.NotifyTypeSuccess {
|
||||||
|
vendorStatus = fakeMerchantAgreeApplyCancel // todo 可能导致订单取消消息重复
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
globals.SugarLogger.Errorf("mtwm unkonw msg:%s", utils.Format4Output(msg, false))
|
||||||
|
}
|
||||||
|
if vendorStatus != "" {
|
||||||
|
orderStatus = &model.OrderStatus{
|
||||||
|
VendorOrderID: orderID,
|
||||||
|
VendorID: model.VendorIDMTWM,
|
||||||
|
OrderType: model.OrderTypeOrder,
|
||||||
|
RefVendorOrderID: orderID,
|
||||||
|
RefVendorID: model.VendorIDMTWM,
|
||||||
|
VendorStatus: vendorStatus,
|
||||||
|
Status: c.getStatusFromVendorStatus(vendorStatus),
|
||||||
|
StatusTime: getTimeFromTimestamp(statusTime),
|
||||||
|
Remark: remark,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return orderStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) postFakeMsg(vendorOrderID, cmd, vendorStatus string) {
|
||||||
|
msg := &mtwmapi.CallbackMsg{
|
||||||
|
Cmd: cmd,
|
||||||
|
FormData: make(url.Values),
|
||||||
|
}
|
||||||
|
timeStr := utils.Int64ToStr(time.Now().Unix())
|
||||||
|
msg.FormData.Set(mtwmapi.KeyOrderID, vendorOrderID)
|
||||||
|
msg.FormData.Set("status", vendorStatus)
|
||||||
|
msg.FormData.Set("timestamp", timeStr)
|
||||||
|
msg.FormData.Set("utime", timeStr)
|
||||||
|
utils.CallFuncAsync(func() {
|
||||||
|
c.onOrderMsg(msg)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
|
||||||
|
if isAcceptIt {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
// err = api.MtwmAPI.OrderReceived(utils.Str2Int64(order.VendorOrderID))
|
||||||
|
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderConfirm(utils.Str2Int64(order.VendorOrderID))
|
||||||
|
if err != nil {
|
||||||
|
if utils.IsErrMatch(err, utils.Int2Str(mtwmapi.ErrCodeOpFailed), []string{
|
||||||
|
"订单已经确认过了",
|
||||||
|
}) {
|
||||||
|
err = nil
|
||||||
|
} else {
|
||||||
|
globals.SugarLogger.Warnf("mtwm AcceptOrRefuseOrder orderID:%s failed with err:%v", order.VendorOrderID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if err == nil {
|
||||||
|
// c.postFakeMsg(order.VendorOrderID, FakeMsgType, mtwmapi.OrderStatusReceived)
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
err = c.CancelOrder(jxcontext.AdminCtx, order, "bu")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
|
||||||
|
if !isSelfDelivery {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
// err = api.MtwmAPI.OrderConfirm(utils.Str2Int64(order.VendorOrderID))
|
||||||
|
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").PreparationMealComplete(utils.Str2Int64(order.VendorOrderID))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
c.postFakeMsg(order.VendorOrderID, FakeMsgType, fakeFinishedPickup)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 美团预定单不能转商家自送
|
||||||
|
func (c *PurchaseHandler) CanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool, err error) {
|
||||||
|
return order.BusinessType != model.BusinessTypeDingshida, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderLogisticsChange2Self(utils.Str2Int64(order.VendorOrderID))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
// 您好,之前的答复已经更正为,调用变更配送状态的接口,会校验门店的配送类型。美团配送的门店即便转自配后因门店配送类型是美团配送所以无法调用接口变更配送状态。可提醒顾客点击确认收货。谢谢
|
||||||
|
// 非自配送门店订单调用OrderArrived好像会报错:{"data":"ng","error":{"code":1038,"msg":"只允许商家配送调用该接口"}}
|
||||||
|
// err = api.MtwmAPI.OrderArrived(utils.Str2Int64(order.VendorOrderID))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderDelivering(utils.Str2Int64(order.VendorOrderID))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderArrived(utils.Str2Int64(order.VendorOrderID))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTimeFromTimestamp(timeStamp int64) time.Time {
|
||||||
|
if timeStamp < 1538103149 { // 立即达订单给的是1(而不是空,0),1538103149不是特殊值,只是一个任意之前的时间,这样写可以处理
|
||||||
|
return utils.DefaultTimeValue
|
||||||
|
}
|
||||||
|
return utils.Timestamp2Time(timeStamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) {
|
||||||
|
err = errors.New("美团外卖还未实现GetOrderRealMobile")
|
||||||
|
return mobile, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
if isAgree {
|
||||||
|
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderRefundAgree(utils.Str2Int64(order.VendorOrderID), reason)
|
||||||
|
} else {
|
||||||
|
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderRefundReject(utils.Str2Int64(order.VendorOrderID), reason)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
if err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderCancel(utils.Str2Int64(order.VendorOrderID), reason, mtwmapi.CancelReasonOther); err == nil {
|
||||||
|
// 调用开放平台接口取消订单,不推送取消订单消息和退款消息。
|
||||||
|
c.postFakeMsg(order.VendorOrderID, mtwmapi.MsgTypeOrderCanceled, mtwmapi.OrderStatusCanceled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
|
||||||
|
// 美团外卖必须要确认订单后才能调整单
|
||||||
|
if order.Status < model.OrderStatusFinishedPickup {
|
||||||
|
err = c.PickupGoods(order, false, ctx.GetUserName())
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
var skuList []*mtwmapi.RefundSku
|
||||||
|
for _, sku := range removedSkuList {
|
||||||
|
skuID := utils.Int2Str(jxutils.GetSkuIDFromOrderSku(sku))
|
||||||
|
skuList = append(skuList, &mtwmapi.RefundSku{
|
||||||
|
AppFoodCode: skuID,
|
||||||
|
SkuID: skuID,
|
||||||
|
Count: sku.Count,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
err = getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").OrderApplyPartRefund(utils.Str2Int64(order.VendorOrderID), reason, skuList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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必须指定")
|
||||||
|
}
|
||||||
|
queryDate = utils.Time2Date(queryDate)
|
||||||
|
|
||||||
|
var vendorStoreIDs []string
|
||||||
|
if vendorStoreID == "" {
|
||||||
|
vendorStoreIDs, err = c.GetAllStoresVendorID(ctx, vendorOrgCode)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vendorStoreIDs = []string{vendorStoreID}
|
||||||
|
}
|
||||||
|
task := tasksch.NewParallelTask("mtwm ListOrders", nil, ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
vendorStoreID := batchItemList[0].(string)
|
||||||
|
var orderIDs []string
|
||||||
|
seqStart := 1
|
||||||
|
i := 0
|
||||||
|
for {
|
||||||
|
batchSize := int(math.Min(math.Pow(2, float64(i*3)), float64(mtwmapi.MaxGap4GetOrderIdByDaySeq)))
|
||||||
|
seqEnd := seqStart + batchSize - 1
|
||||||
|
var tmpOrderIDs []int64
|
||||||
|
if seqStart == seqEnd {
|
||||||
|
if vendorOderID, err2 := getAPI(vendorOrgCode, 0, vendorStoreID).GetOrderIdByDaySeqSingle(vendorStoreID, queryDate, seqStart); err2 == nil {
|
||||||
|
tmpOrderIDs = []int64{vendorOderID}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tmpOrderIDs, err = getAPI(vendorOrgCode, 0, vendorStoreID).GetOrderIdByDaySeq(vendorStoreID, queryDate, seqStart, seqEnd)
|
||||||
|
}
|
||||||
|
if len(tmpOrderIDs) > 0 {
|
||||||
|
for _, v := range tmpOrderIDs {
|
||||||
|
orderIDs = append(orderIDs, utils.Int64ToStr(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil || len(tmpOrderIDs) < batchSize {
|
||||||
|
err = nil
|
||||||
|
break
|
||||||
|
}
|
||||||
|
seqStart = seqEnd + 1
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
retVal = orderIDs
|
||||||
|
return retVal, nil
|
||||||
|
}, vendorStoreIDs)
|
||||||
|
tasksch.HandleTask(task, parentTask, true).Run()
|
||||||
|
orderList, err := task.GetResult(0)
|
||||||
|
if err == nil && len(orderList) > 0 {
|
||||||
|
vendorOrderIDs = make([]string, len(orderList))
|
||||||
|
for k, v := range orderList {
|
||||||
|
vendorOrderIDs[k] = v.(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vendorOrderIDs, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee int64) (err error) {
|
||||||
|
// if globals.EnableMtwmStoreWrite {
|
||||||
|
// err = api.MtwmAPI.OrderUpdateTip(utils.Str2Int64(order.VendorOrderID), jxutils.IntPrice2Standard(tipFee))
|
||||||
|
// }
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetOrderConsigneeNumber(ctx *jxcontext.Context, storeID int, vendorStoreID string) (numberList []*partner.OrderPhoneNumberInfo, err error) {
|
||||||
|
offset := 0
|
||||||
|
for {
|
||||||
|
store, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, "")
|
||||||
|
result, err2 := getAPI(store.VendorOrgCode, storeID, "").OrderBatchPullPhoneNumber(vendorStoreID, offset, mtwmapi.MaxBatchPullPhoneNumberLimit)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
for _, v := range result {
|
||||||
|
v2 := &partner.OrderPhoneNumberInfo{
|
||||||
|
VendorOrderID: utils.Int64ToStr(v.OrderID),
|
||||||
|
PhoneNumber: v.RealPhoneNumber,
|
||||||
|
}
|
||||||
|
if v2.PhoneNumber == "" {
|
||||||
|
v2.PhoneNumber = v.RealOrderPhoneNumber
|
||||||
|
}
|
||||||
|
numberList = append(numberList, v2)
|
||||||
|
}
|
||||||
|
if len(result) <= mtwmapi.MaxBatchPullPhoneNumberLimit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
offset += mtwmapi.MaxBatchPullPhoneNumberLimit
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numberList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetOrderCourierNumber(ctx *jxcontext.Context, storeID int, vendorStoreID string) (numberList []*partner.OrderPhoneNumberInfo, err error) {
|
||||||
|
offset := 0
|
||||||
|
for {
|
||||||
|
store, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, "")
|
||||||
|
result, err2 := getAPI(store.VendorOrgCode, 0, "").OrderGetRiderInfoPhoneNumber(vendorStoreID, offset, mtwmapi.MaxBatchPullPhoneNumberLimit)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
for _, v := range result {
|
||||||
|
numberList = append(numberList, &partner.OrderPhoneNumberInfo{
|
||||||
|
VendorOrderID: utils.Int64ToStr(v.OrderID),
|
||||||
|
PhoneNumber: v.RiderRealPhoneNumber,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(result) <= mtwmapi.MaxBatchPullPhoneNumberLimit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
offset += mtwmapi.MaxBatchPullPhoneNumberLimit
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numberList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) onNumberDowngrade(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) {
|
||||||
|
userNumberMap := make(map[string]*partner.OrderPhoneNumberInfo)
|
||||||
|
courierNumberMap := make(map[string]*partner.OrderPhoneNumberInfo)
|
||||||
|
orderMap := make(map[string]int)
|
||||||
|
ctx := jxcontext.AdminCtx
|
||||||
|
task := tasksch.NewParallelTask("美团外卖平台处理隐私号降级通知", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
step := batchItemList[0].(int)
|
||||||
|
switch step {
|
||||||
|
case 0:
|
||||||
|
userNumberList, err2 := p.GetOrderConsigneeNumber(ctx, 0, "")
|
||||||
|
if err = err2; err == nil {
|
||||||
|
for _, v := range userNumberList {
|
||||||
|
userNumberMap[v.VendorOrderID] = v
|
||||||
|
orderMap[v.VendorOrderID] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
courierNumberList, err2 := p.GetOrderCourierNumber(ctx, 0, "")
|
||||||
|
if err = err2; err == nil {
|
||||||
|
for _, v := range courierNumberList {
|
||||||
|
courierNumberMap[v.VendorOrderID] = v
|
||||||
|
orderMap[v.VendorOrderID] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
orderList := jxutils.StringMap2List(orderMap)
|
||||||
|
if len(orderList) > 0 {
|
||||||
|
updateTask := tasksch.NewParallelTask("美团外卖平台处理隐私号降级通知/处理订单", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), ctx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
vendorOrderID := batchItemList[0].(string)
|
||||||
|
db := dao.GetDB()
|
||||||
|
if userNumberMap[vendorOrderID] != nil {
|
||||||
|
_, err = dao.UpdateEntityByKV(db, &model.GoodsOrder{}, map[string]interface{}{
|
||||||
|
"ConsigneeMobile": userNumberMap[vendorOrderID].PhoneNumber,
|
||||||
|
"ConsigneeMobile2": userNumberMap[vendorOrderID].PhoneNumber,
|
||||||
|
}, map[string]interface{}{
|
||||||
|
model.FieldVendorOrderID: vendorOrderID,
|
||||||
|
model.FieldVendorID: model.VendorIDMTWM,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if courierNumberMap[vendorOrderID] != nil {
|
||||||
|
_, err = dao.UpdateEntityByKV(db, &model.Waybill{}, map[string]interface{}{
|
||||||
|
"CourierMobile": courierNumberMap[vendorOrderID].PhoneNumber,
|
||||||
|
}, map[string]interface{}{
|
||||||
|
"VendorWaybillID": vendorOrderID,
|
||||||
|
"WaybillVendorID": model.VendorIDMTWM,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return retVal, err
|
||||||
|
}, orderList)
|
||||||
|
tasksch.HandleTask(updateTask, task, true).Run()
|
||||||
|
_, err = updateTask.GetResult(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retVal, err
|
||||||
|
}, []int{0, 1, 2})
|
||||||
|
tasksch.HandleTask(task, nil, true).Run()
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) {
|
||||||
|
orderInfo, err := getAPI(vendorOrgCode, 0, vendorStoreID).GetDistributeOrderDetail(vendorOrderID, vendorStoreID)
|
||||||
|
if err == nil {
|
||||||
|
tipFee = jxutils.StandardPrice2Int(orderInfo.TipAmount)
|
||||||
|
}
|
||||||
|
return tipFee, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
err = getAPI(vendorOrgCode, 0, vendorStoreID).OrderModityTips(vendorOrderID, vendorStoreID, jxutils.IntPrice2Standard(tipFee))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) GetSelfTakeCode(ctx *jxcontext.Context, order *model.GoodsOrder) (selfTakeCode string, err error) {
|
||||||
|
return selfTakeCode, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) ComplaintRider(vendorOrderId string, resonID int, resonContent string) (err error) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCancelDeliveryReason 转自配送时取消非专送混合送门店取消理由
|
||||||
|
func (c *PurchaseHandler) GetCancelDeliveryReason(order *model.GoodsOrder) (string, error) {
|
||||||
|
reason, err := getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").GetCancelDeliveryReason(utils.Str2Int64(order.VendorOrderID), order.VendorStoreID)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return reason, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消美团外卖理由转使用三方配送
|
||||||
|
func (c *PurchaseHandler) CancelLogisticsByWmOrderId(order *model.GoodsOrder, reasonCode, detailContent, appPoiCode, orderId string) error {
|
||||||
|
return getAPI(order.VendorOrgCode, jxutils.GetSaleStoreIDFromOrder(order), "").CancelLogisticsByWmOrderId(reasonCode, detailContent, appPoiCode, orderId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取订单配送状态
|
||||||
|
func (c *PurchaseHandler) OrderLogisticsStatus(orderId int64) (int64, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOrderSettleAccounts 获取订单结算信息
|
||||||
|
func (c *PurchaseHandler) GetOrderSettleAccounts(order *model.GoodsOrder) (int64, error) {
|
||||||
|
oderDetail, err := getAPI(order.VendorOrgCode, 0, order.VendorStoreID).OrderGetOrderDetail(utils.Str2Int64(order.VendorOrderID), true)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if poiReceiveDetailStr := utils.Interface2String(oderDetail["poi_receive_detail"]); poiReceiveDetailStr != "" {
|
||||||
|
var poiReceiveDetail *mtwmapi.PoiReceiveDetailInfo
|
||||||
|
utils.UnmarshalUseNumber([]byte(poiReceiveDetailStr), &poiReceiveDetail)
|
||||||
|
if poiReceiveDetail != nil {
|
||||||
|
return poiReceiveDetail.WmPoiReceiveCent, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
251
business/partner/purchase/tao_vegetable/order_afs.go
Normal file
251
business/partner/purchase/tao_vegetable/order_afs.go
Normal 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
|
||||||
|
}
|
||||||
112
business/partner/purchase/tao_vegetable/order_comment.go
Normal file
112
business/partner/purchase/tao_vegetable/order_comment.go
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"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/globals"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RefreshCommentTime = 7 * 24 * time.Hour // 此值必须大于24小时
|
||||||
|
RefreshCommentTimeInterval = 60 * time.Minute
|
||||||
|
BAD_COMMENTS_MAX_MODIFY_TIME = 24 * 6 // 小时
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) StartRefreshComment() {
|
||||||
|
utils.AfterFuncWithRecover(5*time.Second, func() {
|
||||||
|
c.refreshCommentOnce()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) refreshCommentOnce() {
|
||||||
|
c.RefreshComment(time.Now().Add(-RefreshCommentTime), time.Now())
|
||||||
|
utils.AfterFuncWithRecover(RefreshCommentTimeInterval, func() {
|
||||||
|
c.refreshCommentOnce()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func formalizeTagList(mtwmTagList string) (outTagList string) {
|
||||||
|
if mtwmTagList != "" {
|
||||||
|
outTagList = string(utils.Format4Output(strings.Split(mtwmTagList, ","), true))
|
||||||
|
}
|
||||||
|
return outTagList
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) RefreshComment(fromTime, toTime time.Time) (err error) {
|
||||||
|
//storeMapList, err2 := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDMTWM}, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "", "")
|
||||||
|
//if err = err2; err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
endDateStr := time.Now().Add(-24 * time.Hour).Format("20060102")
|
||||||
|
startDateStr := time.Now().Add(-RefreshCommentTime).Format("20060102")
|
||||||
|
storeIDs, _ := dao.GetOrderStoreIDs(dao.GetDB(), fromTime, toTime, model.VendorIDMTWM)
|
||||||
|
task := tasksch.NewParallelTask("mtwm RefreshComment", nil, jxcontext.AdminCtx,
|
||||||
|
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||||||
|
storeID := batchItemList[0].(int)
|
||||||
|
storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDMTWM, "")
|
||||||
|
commentList, err2 := getAPI(storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID).CommentQuery(storeDetail.VendorStoreID, startDateStr, endDateStr, 0, 0, mtwmapi.CommentReplyStatusNotReplied)
|
||||||
|
var orderCommentList []*model.OrderComment
|
||||||
|
if err = err2; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, mtwmComment := range commentList {
|
||||||
|
createdTime, err := utils.TryStr2Time(mtwmComment.CommentTime)
|
||||||
|
if err == nil {
|
||||||
|
orderComment := &model.OrderComment{
|
||||||
|
VendorOrderID: utils.Int64ToStr(mtwmComment.CommentID), // 美团评价不能得到订单号,以评价ID代替
|
||||||
|
VendorID: model.VendorIDMTWM,
|
||||||
|
UserCommentID: utils.Int64ToStr(mtwmComment.CommentID),
|
||||||
|
VendorStoreID: storeDetail.VendorStoreID,
|
||||||
|
TagList: formalizeTagList(mtwmComment.CommentLables),
|
||||||
|
Score: int8(mtwmComment.FoodCommentScore),
|
||||||
|
ModifyDuration: BAD_COMMENTS_MAX_MODIFY_TIME,
|
||||||
|
OriginalMsg: string(utils.MustMarshal(mtwmComment)),
|
||||||
|
IsReplied: int8(mtwmComment.ReplyStatus),
|
||||||
|
StoreID: storeDetail.ID,
|
||||||
|
}
|
||||||
|
if orderComment.IsReplied == 0 {
|
||||||
|
orderComment.Content = mtwmComment.CommentContent
|
||||||
|
orderComment.CommentCreatedAt = createdTime
|
||||||
|
} else {
|
||||||
|
orderComment.Content = mtwmComment.AddComment
|
||||||
|
if updatedTime, err := utils.TryStr2Time(mtwmComment.CommentTime); err == nil {
|
||||||
|
orderComment.CommentCreatedAt = updatedTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
orderCommentList = append(orderCommentList, orderComment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return orderCommentList, nil
|
||||||
|
}, storeIDs)
|
||||||
|
task.Run()
|
||||||
|
resultList, err2 := task.GetResult(0)
|
||||||
|
if err = err2; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var orderCommentList []*model.OrderComment
|
||||||
|
for _, result := range resultList {
|
||||||
|
orderComment := result.(*model.OrderComment)
|
||||||
|
orderCommentList = append(orderCommentList, orderComment)
|
||||||
|
}
|
||||||
|
if len(orderCommentList) > 0 {
|
||||||
|
err = partner.CurOrderManager.OnOrderComments(orderCommentList)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
err = getAPI(vendorOrgCode, orderComment.StoreID, orderComment.VendorStoreID).CommentAddReply(orderComment.VendorStoreID, utils.Str2Int64(orderComment.UserCommentID), replyComment)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
35
business/partner/purchase/tao_vegetable/order_test.go
Normal file
35
business/partner/purchase/tao_vegetable/order_test.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
_ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetOrder(t *testing.T) {
|
||||||
|
// result, err := CurPurchaseHandler.GetOrder("", "33437032333978492")
|
||||||
|
// if err != nil {
|
||||||
|
// t.Fatal(err)
|
||||||
|
// }
|
||||||
|
//t.Log(utils.Format4Output(result, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetOrderStatus(t *testing.T) {
|
||||||
|
result, err := CurPurchaseHandler.GetOrderStatus("", "71884881906304496")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(utils.Format4Output(result, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListOrders(t *testing.T) {
|
||||||
|
result, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, "5873", nil, time.Now(), "14038247")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(utils.Format4Output(result, false))
|
||||||
|
}
|
||||||
485
business/partner/purchase/tao_vegetable/store.go
Normal file
485
business/partner/purchase/tao_vegetable/store.go
Normal file
@@ -0,0 +1,485 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/baseapi/utils/errlist"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxstore/event"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||||||
|
"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"
|
||||||
|
"math"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
opTimeErrReg = regexp.MustCompile(`当前配送营业时间为:([\d:~,]*)`)
|
||||||
|
storeVendorOrgCodeMap = map[string]map[string]string{
|
||||||
|
"589": map[string]string{
|
||||||
|
"firstTag": mtwmapi.MtwmC4Tag, //经营品类
|
||||||
|
"settlementID": "7030017", //结算ID
|
||||||
|
"poiCert": "1,2,5", //资质列表
|
||||||
|
},
|
||||||
|
"5873": map[string]string{
|
||||||
|
"firstTag": mtwmapi.MtwmSCTag,
|
||||||
|
"settlementID": "",
|
||||||
|
"poiCert": "1,2,5,6",
|
||||||
|
},
|
||||||
|
"4123": map[string]string{
|
||||||
|
"firstTag": mtwmapi.MtwmSGTag,
|
||||||
|
"settlementID": "6572945",
|
||||||
|
"poiCert": "1,5",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
poiCertMap = map[string]string{
|
||||||
|
"1": "门脸图",
|
||||||
|
"2": "环境图",
|
||||||
|
"5": "营业执照",
|
||||||
|
"6": "食品经营许可证",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type tEbaiStoreInfo struct {
|
||||||
|
model.Store
|
||||||
|
VendorStoreID string `orm:"column(vendor_store_id)"`
|
||||||
|
RealLastOperator string
|
||||||
|
EbaiStoreStatus int
|
||||||
|
SyncStatus int
|
||||||
|
|
||||||
|
ProvinceID int `orm:"column(province_id)"`
|
||||||
|
CityID int `orm:"column(city_id)"`
|
||||||
|
DistrictID int `orm:"column(district_id)"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorStoreName string) (retVal *dao.StoreDetail, err error) {
|
||||||
|
result, err := getAPIWithoutToken(vendorOrgCode).PoiGet(vendorStoreID)
|
||||||
|
if err == nil {
|
||||||
|
retVal = &dao.StoreDetail{
|
||||||
|
Store: model.Store{
|
||||||
|
Address: result.Address,
|
||||||
|
Tel1: result.Phone,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
retVal.OriginalName = result.Name
|
||||||
|
_, retVal.Name = jxutils.SplitStoreName(retVal.OriginalName, partner.StoreNameSeparator, globals.StoreNameMtwm)
|
||||||
|
|
||||||
|
retVal.SetOpTime(openTimeMtwm2JX(result.ShippingTime))
|
||||||
|
retVal.Status = bizStatusMtwm2JX(result.OpenLevel, result.IsOnline)
|
||||||
|
|
||||||
|
tel2 := result.StandbyTel
|
||||||
|
if tel2 != "" && tel2 != retVal.Tel1 {
|
||||||
|
retVal.Tel2 = tel2
|
||||||
|
}
|
||||||
|
|
||||||
|
retVal.Lng = int(result.Longitude)
|
||||||
|
retVal.Lat = int(result.Latitude)
|
||||||
|
|
||||||
|
lng := jxutils.IntCoordinate2Standard(retVal.Lng)
|
||||||
|
lat := jxutils.IntCoordinate2Standard(retVal.Lat)
|
||||||
|
db := dao.GetDB()
|
||||||
|
retVal.DistrictCode = api.AutonaviAPI.GetCoordinateDistrictCode(lng, lat)
|
||||||
|
city, err := dao.GetPlaceByCode(db, result.CityID)
|
||||||
|
retVal.CityName = city.Name
|
||||||
|
retVal.CityCode = result.CityID
|
||||||
|
|
||||||
|
poiCode := result.AppPoiCode
|
||||||
|
retVal.VendorStoreID = vendorStoreID
|
||||||
|
retVal.ID = int(utils.Str2Int64WithDefault(poiCode, 0))
|
||||||
|
retVal.DeliveryRangeType = model.DeliveryRangeTypePolygon
|
||||||
|
var deliveryRangeInfo []map[string]interface{}
|
||||||
|
deliveryRangeInfo, err = getAPIWithoutToken(vendorOrgCode).ShippingFetch(poiCode)
|
||||||
|
if err != nil {
|
||||||
|
deliveryRangeInfo, err = getAPIWithoutToken(vendorOrgCode).ShippingList(poiCode)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
if len(deliveryRangeInfo) > 0 {
|
||||||
|
retVal.DeliveryRange = rangeMtwm2JX(deliveryRangeInfo[0]["area"].(string))
|
||||||
|
logisticsCode := utils.Interface2String(deliveryRangeInfo[0]["logistics_code"])
|
||||||
|
if logisticsCode == "" || logisticsCode == mtwmapi.PeiSongTypeSelf {
|
||||||
|
retVal.DeliveryType = scheduler.StoreDeliveryTypeByStore
|
||||||
|
} else {
|
||||||
|
retVal.DeliveryType = scheduler.StoreDeliveryTypeByPlatform
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retVal, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
func (p *PurchaseHandler) CreateStore(db *dao.DaoDB, storeID int, userName string) (err error) {
|
||||||
|
return p.UpdateStore(db, storeID, userName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) CreateStore2(db *dao.DaoDB, storeID int, userName string, params map[string]interface{}, storeDetail *dao.StoreDetail) (vendorStoreID string, err error) {
|
||||||
|
vendorOrgCode := params["vendorOrgCode"].(string)
|
||||||
|
if vendorOrgCode == "" {
|
||||||
|
return "", fmt.Errorf("平台账号必传!")
|
||||||
|
}
|
||||||
|
cityName := storeDetail.CityName
|
||||||
|
if strings.Contains(cityName, "市") {
|
||||||
|
cityName = strings.Replace(cityName, "市", "", strings.LastIndex(cityName, "市"))
|
||||||
|
}
|
||||||
|
shippingTime := ""
|
||||||
|
if storeDetail.OpenTime1 != 0 && storeDetail.CloseTime1 != 0 {
|
||||||
|
shippingTime += jxutils.JxOperationTime2StrTime(storeDetail.OpenTime1)
|
||||||
|
shippingTime += "-"
|
||||||
|
shippingTime += jxutils.JxOperationTime2StrTime(storeDetail.CloseTime1)
|
||||||
|
if storeDetail.OpenTime2 != 0 && storeDetail.CloseTime2 != 0 {
|
||||||
|
shippingTime += ","
|
||||||
|
shippingTime += jxutils.JxOperationTime2StrTime(storeDetail.OpenTime2)
|
||||||
|
shippingTime += "-"
|
||||||
|
shippingTime += jxutils.JxOperationTime2StrTime(storeDetail.CloseTime2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vendorInfoMap := storeVendorOrgCodeMap[vendorOrgCode]
|
||||||
|
poiSettleSaveParam := &mtwmapi.PoiSettleSaveParam{
|
||||||
|
Type: 1, //创建
|
||||||
|
ApplyInfos: []*mtwmapi.ApplyInfo{
|
||||||
|
&mtwmapi.ApplyInfo{
|
||||||
|
AppPoiCode: utils.Int2Str(storeDetail.ID),
|
||||||
|
SettlementID: utils.Str2Int(vendorInfoMap["settlementID"]), //结算ID,暂时还没得
|
||||||
|
MultiPoiBasicInfo: &mtwmapi.MultiPoiBasicInfo{
|
||||||
|
Name: params["vendorStoreName"].(string),
|
||||||
|
City: cityName,
|
||||||
|
Address: storeDetail.Address,
|
||||||
|
Longitude: utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lng)),
|
||||||
|
Latitude: utils.Float64ToStr(jxutils.IntCoordinate2Standard(storeDetail.Lat)),
|
||||||
|
FirstTag: vendorInfoMap["firstTag"],
|
||||||
|
CallCenter: storeDetail.Tel1,
|
||||||
|
ContactPhone: storeDetail.Tel1,
|
||||||
|
ContactName: storeDetail.IDName,
|
||||||
|
EcommerceAccountPhone: "18048531223", //石总的手机
|
||||||
|
ShippingTime: shippingTime,
|
||||||
|
},
|
||||||
|
MultiPoiShippingInfo: &mtwmapi.MultiPoiShippingInfo{
|
||||||
|
ShippingType: 5, //1:商家自配 5:美团专送,101:美团快送
|
||||||
|
//美团专送不需要输下面这俩
|
||||||
|
// MinPrice: params["minPrice"].(float64),
|
||||||
|
// ShippingFee: params["shippingFee"].(float64),
|
||||||
|
},
|
||||||
|
//资质
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
switchCertType := func(certType string) (licensePic, licenseSocialCreditCode, licenseNumber, licenseLegalPerson, licenseAddress, licenseValidStartDate, licenseValidity string, isLongTime int) {
|
||||||
|
switch certType {
|
||||||
|
case "1":
|
||||||
|
licensePic = storeDetail.StoreFrontPic
|
||||||
|
case "2":
|
||||||
|
licensePic = storeDetail.StoreInPic
|
||||||
|
case "5":
|
||||||
|
licensePic = storeDetail.Licence
|
||||||
|
licenseSocialCreditCode = storeDetail.LicenceCode
|
||||||
|
licenseNumber = storeDetail.LicenceCode
|
||||||
|
licenseLegalPerson = storeDetail.LicenceOwnerName
|
||||||
|
licenseAddress = storeDetail.LicenceAddress
|
||||||
|
licenseValidStartDate = storeDetail.LicenceValid
|
||||||
|
if storeDetail.LicenceExpire == "" {
|
||||||
|
isLongTime = 1
|
||||||
|
} else {
|
||||||
|
licenseValidity = storeDetail.LicenceExpire
|
||||||
|
}
|
||||||
|
case "6":
|
||||||
|
licensePic = storeDetail.Licence2Image
|
||||||
|
licenseSocialCreditCode = storeDetail.Licence2Code
|
||||||
|
licenseNumber = storeDetail.Licence2Code
|
||||||
|
licenseLegalPerson = storeDetail.LicenceOwnerName
|
||||||
|
licenseAddress = storeDetail.LicenceAddress
|
||||||
|
licenseValidStartDate = storeDetail.Licence2Valid
|
||||||
|
if storeDetail.Licence2Expire == "" {
|
||||||
|
isLongTime = 1
|
||||||
|
} else {
|
||||||
|
licenseValidity = storeDetail.Licence2Expire
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return licensePic, licenseSocialCreditCode, licenseNumber, licenseLegalPerson, licenseAddress, licenseValidStartDate, licenseValidity, isLongTime
|
||||||
|
}
|
||||||
|
var certs []*mtwmapi.MultiPoiCertInfo
|
||||||
|
for _, v := range strings.Split(vendorInfoMap["poiCert"], ",") {
|
||||||
|
cert := &mtwmapi.MultiPoiCertInfo{
|
||||||
|
Type: utils.Str2Int(v),
|
||||||
|
LicenseName: poiCertMap[v],
|
||||||
|
}
|
||||||
|
cert.LicensePic, cert.LicenseSocialCreditCode, cert.LicenseNumber, cert.LicenseLegalPerson, cert.LicenseAddress, cert.LicenseValidStartDate, cert.LicenseValidity, cert.IsLongTime = switchCertType(v)
|
||||||
|
certs = append(certs, cert)
|
||||||
|
}
|
||||||
|
poiSettleSaveParam.ApplyInfos[0].MultiPoiCertInfos = certs
|
||||||
|
mtapi := getAPIWithoutToken(vendorOrgCode)
|
||||||
|
if vendorStoreID, err = mtapi.PoiSettleSave(poiSettleSaveParam); err == nil {
|
||||||
|
err = mtapi.PoiSettleAuditSubmit([]string{vendorStoreID})
|
||||||
|
}
|
||||||
|
return vendorStoreID, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) {
|
||||||
|
var name string
|
||||||
|
if db == nil {
|
||||||
|
db = dao.GetDB()
|
||||||
|
}
|
||||||
|
mtapi := getAPI(getStoreVendorOrgCode(storeID), storeID, "")
|
||||||
|
//获取本地store信息
|
||||||
|
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDMTWM, "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
errList := errlist.New()
|
||||||
|
//获取平台store信息
|
||||||
|
remoteStoreInfo, err := mtapi.PoiGet(storeDetail.VendorStoreID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mergedStoreStatus := jxutils.MergeStoreStatus(storeDetail.Status, storeDetail.VendorStatus)
|
||||||
|
name = remoteStoreInfo.Name
|
||||||
|
if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreName) != 0 {
|
||||||
|
if storeDetail.VendorStoreName != "" {
|
||||||
|
name = storeDetail.VendorStoreName
|
||||||
|
}
|
||||||
|
// else {
|
||||||
|
// name = jxutils.ComposeStoreName(storeDetail.Store.Name, model.VendorIDMTWM)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
store := fmt.Sprintf("门店id:%d,门店名称:%s,第三方门店状态:%d,本地修改前门店状态%d,本地门店修改后状态:%d,第三方平台Id(美团):%s", storeID, remoteStoreInfo.Name, remoteStoreInfo.IsOnline, storeDetail.Status, mergedStoreStatus, storeDetail.VendorOrgCode)
|
||||||
|
event.AddOperateEvent(jxcontext.AdminCtx, jxcontext.AdminCtx.GetTrackInfo(), store, "", "", 10, "UpdateStore")
|
||||||
|
// openLevel, isOnline := bizStatusJX2Mtwm(mergedStoreStatus)
|
||||||
|
//TODO 美团暂时不用那个电话
|
||||||
|
phone := storeDetail.Tel1
|
||||||
|
// if storeDetail.MarketManPhone != "" {
|
||||||
|
// phone = storeDetail.MarketManPhone
|
||||||
|
// } else {
|
||||||
|
// phone = model.VendorStoreTel
|
||||||
|
// }
|
||||||
|
params := map[string]interface{}{
|
||||||
|
"name": name, //jxutils.ComposeStoreName(storeDetail.Store.Name, model.VendorIDMTWM),
|
||||||
|
"address": storeDetail.Address, // 美团好像地址也不能改的?
|
||||||
|
"longitude": jxutils.IntCoordinate2Standard(int(remoteStoreInfo.Longitude)),
|
||||||
|
"latitude": jxutils.IntCoordinate2Standard(int(remoteStoreInfo.Latitude)),
|
||||||
|
"phone": phone,
|
||||||
|
"shipping_fee": remoteStoreInfo.ShippingFee,
|
||||||
|
"shipping_time": remoteStoreInfo.ShippingTime,
|
||||||
|
"open_level": remoteStoreInfo.OpenLevel,
|
||||||
|
"is_online": remoteStoreInfo.IsOnline,
|
||||||
|
"third_tag_name": remoteStoreInfo.ThirdTagName,
|
||||||
|
"promotion_info": storeDetail.PromoteInfo,
|
||||||
|
}
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
errList.AddErr(mtapi.PoiSave(storeDetail.VendorStoreID, params))
|
||||||
|
}
|
||||||
|
// PoiSave有时会报错:商家已接入美团配送,不可修改门店配送相关信息,这里放弃信息修改
|
||||||
|
// if err != nil {
|
||||||
|
// if utils.IsErrMatch(err, utils.Int2Str(mtwmapi.ErrCodeCanNotModifyStoreDeliveryInfo), nil) {
|
||||||
|
// if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreStatus) != 0 {
|
||||||
|
// err = p.UpdateStoreStatus(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, mergedStoreStatus)
|
||||||
|
// } else {
|
||||||
|
// err = nil
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// errList.AddErr(err)
|
||||||
|
// }
|
||||||
|
if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreStatus) != 0 {
|
||||||
|
errList.AddErr(p.UpdateStoreStatus(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, mergedStoreStatus))
|
||||||
|
}
|
||||||
|
errList.AddErr(p.UpdateStoreOpTime(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, storeDetail.GetOpTimeList()))
|
||||||
|
// errList.AddErr(p.UpdateStoreBoxFee(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID))
|
||||||
|
return errList.GetErrListAsOne()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) {
|
||||||
|
return "", errors.New("美团外卖不支持此操作")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) onStoreStatusChanged(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) {
|
||||||
|
var err error
|
||||||
|
vendorStoreID := msg.FormData.Get("app_poi_code")
|
||||||
|
storeStatus := 0
|
||||||
|
if msg.Cmd == mtwmapi.MsgTypeStoreStatusChanged {
|
||||||
|
poiStatus := int(utils.Str2Int64(msg.FormData.Get("poi_status")))
|
||||||
|
if poiStatus == mtwmapi.MsgPoiStatusOpened {
|
||||||
|
storeStatus = model.StoreStatusOpened
|
||||||
|
} else if poiStatus == mtwmapi.MsgPoiStatusClosed {
|
||||||
|
storeStatus = model.StoreStatusClosed
|
||||||
|
} else if poiStatus == mtwmapi.MsgPoiStatusOffline {
|
||||||
|
storeStatus = model.StoreStatusDisabled
|
||||||
|
} else {
|
||||||
|
storeStatus, err = p.GetStoreStatus(jxcontext.AdminCtx, "", 0, vendorStoreID)
|
||||||
|
}
|
||||||
|
} else if msg.Cmd == mtwmapi.MsgTypeStoreAuditStatusChanged {
|
||||||
|
auditDetails := []map[string]interface{}{}
|
||||||
|
auditDetail := msg.FormData.Get("audit_detail")
|
||||||
|
openFlag := false
|
||||||
|
openCount := 0
|
||||||
|
closeFlag := false
|
||||||
|
if err = json.Unmarshal([]byte(auditDetail), &auditDetails); err == nil {
|
||||||
|
for _, v := range auditDetails {
|
||||||
|
if v["module_status"].(string) == "3" || v["module_status"].(string) == "5" || v["module_status"].(string) == "7" {
|
||||||
|
closeFlag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if v["module_status"].(string) == "6" {
|
||||||
|
openCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if openCount == len(auditDetails) {
|
||||||
|
openFlag = true
|
||||||
|
}
|
||||||
|
if closeFlag {
|
||||||
|
storeStatus = model.StoreStatusDisabled
|
||||||
|
} else if openFlag {
|
||||||
|
storeStatus = model.StoreStatusOpened
|
||||||
|
} else {
|
||||||
|
storeStatus = model.StoreStatusClosed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
err = partner.CurStoreManager.OnStoreStatusChanged(vendorStoreID, model.VendorIDMTWM, storeStatus)
|
||||||
|
}
|
||||||
|
response = mtwmapi.Err2CallbackResponse(err, "")
|
||||||
|
// 操作日志(美团外卖)
|
||||||
|
ctx := jxcontext.AdminCtx
|
||||||
|
store := fmt.Sprintf("美团外卖回调门店改变回调(营业状态/审核状态):门店id:%s,美团门店状态:%d.[121营业,120休息,18上线,19下线],本地修改后状态[%d]", vendorStoreID, int(utils.Str2Int64(msg.FormData.Get("poi_status"))), storeStatus)
|
||||||
|
event.AddOperateEvent(ctx, ctx.GetTrackInfo(), store, "", "", 10, "UpdateStore")
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) {
|
||||||
|
result, err := getAPI(vendorOrgCode, storeID, "").PoiGet(vendorStoreID)
|
||||||
|
if err == nil {
|
||||||
|
return bizStatusMtwm2JX(result.OpenLevel, result.IsOnline), nil
|
||||||
|
}
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) {
|
||||||
|
openLevel, isOnline := bizStatusJX2Mtwm(status)
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
if isOnline != mtwmapi.PoiStatusOnline {
|
||||||
|
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiOffline(vendorStoreID)
|
||||||
|
} else {
|
||||||
|
if err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiOnline(vendorStoreID); err == nil { // 这个函数成功返回也并不表示上线成功。。。
|
||||||
|
remoteStoreInfo, err2 := getAPI(vendorOrgCode, storeID, vendorStoreID).PoiGet(vendorStoreID)
|
||||||
|
if err = err2; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if remoteStoreInfo.IsOnline == mtwmapi.PoiStatusOnline {
|
||||||
|
if openLevel == mtwmapi.PoiOpenLevelHaveRest {
|
||||||
|
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiClose(vendorStoreID)
|
||||||
|
} else {
|
||||||
|
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiOpen(vendorStoreID)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = errors.New("门店还未上线,不能修改营业状态")
|
||||||
|
}
|
||||||
|
store := fmt.Sprintf("美团外卖回调门店改变回调(营业状态/审核状态):门店id:%s,美团门店状态:%d.[121营业,120休息,18上线,19下线],本地修改后状态[%d]", vendorStoreID, remoteStoreInfo.OpenLevel, openLevel)
|
||||||
|
event.AddOperateEvent(ctx, ctx.GetTrackInfo(), store, "", "", 10, "UpdateStore")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func errOpStr2Int16(str string) []int16 {
|
||||||
|
list := strings.Split(str, "~")
|
||||||
|
if len(list) >= 2 {
|
||||||
|
return []int16{jxutils.StrTime2JxOperationTime(list[0]+":00", 0), jxutils.StrTime2JxOperationTime(list[1]+":00", 2359)}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOpTimeListFromErr(err error) (opTimeList []int16) {
|
||||||
|
if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == mtwmapi.ErrCodeOpFailed {
|
||||||
|
if result := opTimeErrReg.FindStringSubmatch(errExt.ErrMsg()); len(result) >= 2 {
|
||||||
|
timeStrList := strings.Split(result[1], ",")
|
||||||
|
for _, v := range timeStrList {
|
||||||
|
v = utils.TrimBlankChar(v)
|
||||||
|
if len(v) == len("00:00~02:00") {
|
||||||
|
opTimeList = append(opTimeList, errOpStr2Int16(v)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return opTimeList
|
||||||
|
}
|
||||||
|
|
||||||
|
// 此函数只是简单实现,不支持区间切分,只做单一区间限制
|
||||||
|
func constrainOpTimeList(opTimeList, validOpTimeList []int16) (newOpTimeList []int16) {
|
||||||
|
for k := 0; k < len(opTimeList); k += 2 {
|
||||||
|
beginTime := opTimeList[k]
|
||||||
|
endTime := opTimeList[k+1]
|
||||||
|
for k2 := 0; k2 < len(validOpTimeList); k2 += 2 {
|
||||||
|
beginTime2 := validOpTimeList[k2]
|
||||||
|
endTime2 := validOpTimeList[k2+1]
|
||||||
|
if beginTime >= beginTime2 && beginTime <= endTime2 {
|
||||||
|
newOpTimeList = append(newOpTimeList, beginTime)
|
||||||
|
newOpTimeList = append(newOpTimeList, int16(math.Min(float64(endTime), float64(endTime2))))
|
||||||
|
} else if beginTime2 >= beginTime && beginTime2 <= endTime {
|
||||||
|
newOpTimeList = append(newOpTimeList, beginTime2)
|
||||||
|
newOpTimeList = append(newOpTimeList, int16(math.Min(float64(endTime), float64(endTime2))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newOpTimeList
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) {
|
||||||
|
shippingTime := openTimeJX2Mtwm(opTimeList)
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiShipTimeUpdate(vendorStoreID, shippingTime)
|
||||||
|
if err != nil {
|
||||||
|
shippingTime = ""
|
||||||
|
if validOpTimeList := getOpTimeListFromErr(err); len(validOpTimeList) > 0 {
|
||||||
|
shippingTime = openTimeJX2Mtwm(constrainOpTimeList(opTimeList, validOpTimeList))
|
||||||
|
}
|
||||||
|
if shippingTime != "" {
|
||||||
|
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiShipTimeUpdate(vendorStoreID, shippingTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) {
|
||||||
|
vendorStoreIDs, err = getAPIWithoutToken(vendorOrgCode).PoiGetIDs()
|
||||||
|
return vendorStoreIDs, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) UpdateStoreBoxFee(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (err error) {
|
||||||
|
boxFee, err := dao.GetSysConfigAsInt64(dao.GetDB(), model.ConfigSysMtwmBoxFee)
|
||||||
|
if err == nil {
|
||||||
|
if globals.EnableMtwmStoreWrite && globals.IsProductEnv() {
|
||||||
|
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PackagePriceUpdate(vendorStoreID, 1, int(boxFee))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) UpdateStoreLineStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, lineStatus int) (err error) {
|
||||||
|
if lineStatus == model.StoreStatusOpened {
|
||||||
|
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiOnline(vendorStoreID)
|
||||||
|
} else {
|
||||||
|
err = getAPI(vendorOrgCode, storeID, vendorStoreID).PoiOffline(vendorStoreID)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
763
business/partner/purchase/tao_vegetable/store_sku2.go
Normal file
763
business/partner/purchase/tao_vegetable/store_sku2.go
Normal file
@@ -0,0 +1,763 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"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/jxutils/tasksch"
|
||||||
|
"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/business/partner/putils"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
updateTypeStock = iota
|
||||||
|
updateTypeStatus
|
||||||
|
updateTypePrice
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
sensitiveWordRegexp = regexp.MustCompile(`包含敏感词:(\[.*\])`)
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) {
|
||||||
|
switch funcID {
|
||||||
|
case partner.FuncUpdateStoreSkusStock, partner.FuncUpdateStoreSkusStatus, partner.FuncUpdateStoreSkusPrice:
|
||||||
|
batchSize = mtwmapi.MaxStoreSkuBatchSize
|
||||||
|
case partner.FuncDeleteStoreSkus:
|
||||||
|
batchSize = mtwmapi.MaxBatchDeleteSize
|
||||||
|
case partner.FuncCreateStoreSkus:
|
||||||
|
batchSize = 1 // 可考虑用批量操作
|
||||||
|
case partner.FuncUpdateStoreSkus:
|
||||||
|
batchSize = 1 // mtwmapi.MaxStoreSkuBatchSize
|
||||||
|
case partner.FuncGetStoreSkusFullInfo:
|
||||||
|
batchSize = 1
|
||||||
|
case partner.FuncCreateActs:
|
||||||
|
batchSize = mtwmapi.MaxRetailDiscountCreateBatchSize
|
||||||
|
case partner.FuncCancelActs:
|
||||||
|
batchSize = mtwmapi.MaxRetailDiscountDeleteBatchSize
|
||||||
|
}
|
||||||
|
return batchSize
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStoreVendorOrgCode(storeID int) (vendorOrgCode string) {
|
||||||
|
if storeMap, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDTaoVegetable, ""); storeMap != nil {
|
||||||
|
return storeMap.VendorOrgCode
|
||||||
|
}
|
||||||
|
return vendorOrgCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// 门店分类
|
||||||
|
func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) {
|
||||||
|
remoteCats, err := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatList(vendorStoreID)
|
||||||
|
if err == nil {
|
||||||
|
cats = convertVendorCatList(remoteCats)
|
||||||
|
}
|
||||||
|
return cats, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertVendorCatList(remoteCats []*mtwmapi.RetailCategoryInfo) (cats []*partner.BareCategoryInfo) {
|
||||||
|
for _, rCat := range remoteCats {
|
||||||
|
cat := &partner.BareCategoryInfo{
|
||||||
|
VendorCatID: rCat.Code,
|
||||||
|
Name: rCat.Name,
|
||||||
|
Level: rCat.Level,
|
||||||
|
Seq: rCat.Sequence,
|
||||||
|
Children: convertVendorCatList(rCat.Children),
|
||||||
|
}
|
||||||
|
if cat.VendorCatID == "" {
|
||||||
|
cat.VendorCatID = rCat.Name
|
||||||
|
}
|
||||||
|
cats = append(cats, cat)
|
||||||
|
}
|
||||||
|
return cats
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) {
|
||||||
|
return mtwmapi.IsErrCategoryExist(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) {
|
||||||
|
return mtwmapi.IsErrCategoryNotExist(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func catCode2Str(catCode int) (catCodeStr string) {
|
||||||
|
if catCode > 0 {
|
||||||
|
catCodeStr = utils.Int2Str(catCode)
|
||||||
|
}
|
||||||
|
return catCodeStr
|
||||||
|
}
|
||||||
|
|
||||||
|
func tryCatName2Code(originName string) (catCodeStr string) {
|
||||||
|
if intValue := utils.Str2Int64WithDefault(originName, 0); intValue > 0 {
|
||||||
|
catCodeStr = utils.Int64ToStr(intValue)
|
||||||
|
if catCodeStr != originName {
|
||||||
|
catCodeStr = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return catCodeStr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
|
||||||
|
level := 1
|
||||||
|
if storeCat.ParentCatName != "" {
|
||||||
|
level = 2
|
||||||
|
}
|
||||||
|
originName := ""
|
||||||
|
catName := storeCat.Name
|
||||||
|
catCode := storeCat.ID
|
||||||
|
|
||||||
|
subCatName := ""
|
||||||
|
subCatCode := 0
|
||||||
|
if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 {
|
||||||
|
// 修改一级分类
|
||||||
|
originName = storeCat.VendorCatID
|
||||||
|
}
|
||||||
|
if level == 2 { // 二级分类
|
||||||
|
// 创建二级分类
|
||||||
|
originName = storeCat.ParentVendorCatID
|
||||||
|
catName = storeCat.ParentCatName
|
||||||
|
catCode = storeCat.ParentID
|
||||||
|
subCatName = storeCat.Name
|
||||||
|
subCatCode = storeCat.ID
|
||||||
|
if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 {
|
||||||
|
// 修改二级分类
|
||||||
|
originName = storeCat.VendorCatID
|
||||||
|
catName = storeCat.Name
|
||||||
|
catCode = storeCat.ID
|
||||||
|
subCatName = ""
|
||||||
|
subCatCode = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if catName == "" {
|
||||||
|
panic("catName is empty")
|
||||||
|
}
|
||||||
|
catName = utils.FilterEmoji(catName)
|
||||||
|
subCatName = utils.FilterEmoji(subCatName)
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
param4Update := &mtwmapi.Param4UpdateCat{
|
||||||
|
CategoryCodeOrigin: tryCatName2Code(originName),
|
||||||
|
CategoryNameOrigin: originName,
|
||||||
|
CategoryCode: catCode2Str(catCode),
|
||||||
|
SecondaryCategoryCode: catCode2Str(subCatCode),
|
||||||
|
SecondaryCategoryName: subCatName,
|
||||||
|
Sequence: storeCat.Seq,
|
||||||
|
}
|
||||||
|
api := getAPI(storeCat.VendorOrgCode, storeID, vendorStoreID)
|
||||||
|
err = api.RetailCatUpdate(vendorStoreID, catName, param4Update)
|
||||||
|
if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 && p.IsErrCategoryNotExist(err) && originName != "" { // 修改分类名,但分类不存在
|
||||||
|
storeCat.CatSyncStatus |= model.SyncFlagNewMask
|
||||||
|
err = p.CreateStoreCategory(ctx, storeID, vendorStoreID, storeCat)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 门店内存在重复的分类:【柑桔柚类】 【底料】,请先删除重复分类后再操作。
|
||||||
|
if err != nil && strings.Contains(err.Error(), "门店内存在重复的分类:") {
|
||||||
|
for _, v := range deleteRepeatCat(err.Error()) {
|
||||||
|
if len(v) > 0 {
|
||||||
|
if err2 := api.RetailCatDelete(vendorStoreID, "", v, model.YES); err != nil {
|
||||||
|
globals.SugarLogger.Errorf("RetailCatDelete delete err : [%v]", err2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
// storeCat.VendorCatID = utils.FilterEmoji(storeCat.Name)
|
||||||
|
storeCat.VendorCatID = utils.Int2Str(storeCat.ID)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// deleteRepeatCat 门店内存在重复的分类:【柑桔柚类】 【底料】 【火锅】,请先删除重复分类后再操作。
|
||||||
|
func deleteRepeatCat(param string) []string {
|
||||||
|
firstIndex := strings.Index(param, "【")
|
||||||
|
lastIndex := strings.LastIndex(param, "】")
|
||||||
|
newParam := param[firstIndex:lastIndex]
|
||||||
|
deleteCat := make([]string, 0, 0)
|
||||||
|
for _, v := range strings.Split(newParam, "【") {
|
||||||
|
if strings.TrimSpace(v) == "" {
|
||||||
|
continue
|
||||||
|
} else if strings.Contains(v, "【") {
|
||||||
|
for _, v2 := range strings.Split(v, "【") {
|
||||||
|
if strings.TrimSpace(v) == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(v2) != "" {
|
||||||
|
deleteCat = append(deleteCat, v2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if strings.Contains(v, "】") {
|
||||||
|
for _, v3 := range strings.Split(v, "】") {
|
||||||
|
if strings.TrimSpace(v3) == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(v3) != "" {
|
||||||
|
deleteCat = append(deleteCat, v3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
deleteCat = append(deleteCat, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deleteCat
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
|
||||||
|
return p.CreateStoreCategory(ctx, storeID, vendorStoreID, storeCat)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) {
|
||||||
|
if false {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatDelete(vendorStoreID, tryCatName2Code(vendorCatID), vendorCatID, model.NO)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var catCodes []string
|
||||||
|
if catCode := tryCatName2Code(vendorCatID); catCode != "" {
|
||||||
|
catCodes = []string{catCode}
|
||||||
|
}
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
if level == 1 {
|
||||||
|
err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, catCodes, []string{vendorCatID}, nil, nil, nil)
|
||||||
|
} else {
|
||||||
|
err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, nil, nil, catCodes, []string{vendorCatID}, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//批量更新商品进货价
|
||||||
|
func BatchSetRestockingPrice(ctx *jxcontext.Context, storeID int, vendorStoreID string, param []*mtwmapi.SpuData) error {
|
||||||
|
if err := getAPI(getStoreVendorOrgCode(storeID), storeID, "").BatchSetRestockingPrice(ctx.GetTrackInfo(), vendorStoreID, param); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 门店商品
|
||||||
|
|
||||||
|
// 多门店平台不需要实现这个接口
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) {
|
||||||
|
return mtwmapi.IsErrSkuNotExist(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// func duplicateStoreSkuList(storeSkuList []*dao.StoreSkuSyncInfo, index int) (newStoreSkuList []*dao.StoreSkuSyncInfo) {
|
||||||
|
// newStoreSkuList = make([]*dao.StoreSkuSyncInfo, len(storeSkuList))
|
||||||
|
// for k, v := range storeSkuList {
|
||||||
|
// tmp := *v
|
||||||
|
// tmp.SkuName = fmt.Sprintf("%s.%d", tmp.SkuName, index)
|
||||||
|
// tmp.SkuID = index*1000000 + tmp.SkuID
|
||||||
|
// newStoreSkuList[k] = &tmp
|
||||||
|
// }
|
||||||
|
// return newStoreSkuList
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||||
|
failedList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false)
|
||||||
|
// if err == nil && vendorStoreID == specialStoreID {
|
||||||
|
// for i := 0; i < 2; i++ {
|
||||||
|
// p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return failedList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||||
|
failedList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true)
|
||||||
|
// if err == nil && vendorStoreID == specialStoreID {
|
||||||
|
// for i := 0; i < 2; i++ {
|
||||||
|
// p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return failedList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对于多门店平台来说,storeSkuList中只有SkuID与VendorSkuID有意义
|
||||||
|
func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo, isCreate bool) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||||
|
var syncType string
|
||||||
|
foodDataList := make([]map[string]interface{}, len(storeSkuList))
|
||||||
|
if isCreate {
|
||||||
|
syncType = "创建商品"
|
||||||
|
} else {
|
||||||
|
syncType = "更新商品"
|
||||||
|
}
|
||||||
|
for i, storeSku := range storeSkuList {
|
||||||
|
isNeedUpdatePrice := isCreate //storeSku.SkuSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0
|
||||||
|
foodData := make(map[string]interface{})
|
||||||
|
foodDataList[i] = foodData
|
||||||
|
foodData[mtwmapi.KeyAppFoodCode] = utils.Int2Str(storeSku.SkuID)
|
||||||
|
skus := []map[string]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"sku_id": foodData[mtwmapi.KeyAppFoodCode],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
foodData["skus"] = skus
|
||||||
|
foodData["name"] = utils.LimitUTF8StringLen(storeSku.SkuName, mtwmapi.MaxSkuNameCharCount)
|
||||||
|
foodData["description"] = storeSku.Comment
|
||||||
|
if isNeedUpdatePrice {
|
||||||
|
foodData["price"] = jxutils.IntPrice2Standard(storeSku.VendorPrice)
|
||||||
|
}
|
||||||
|
if storeSku.MinOrderCount != 0 {
|
||||||
|
foodData["min_order_count"] = storeSku.MinOrderCount
|
||||||
|
} else {
|
||||||
|
foodData["min_order_count"] = 1
|
||||||
|
}
|
||||||
|
foodData["unit"] = storeSku.Unit
|
||||||
|
attr := SwitchAttr(storeSku.VendorVendorCatID)
|
||||||
|
if attr != "" {
|
||||||
|
foodData["common_attr_value"] = attr
|
||||||
|
}
|
||||||
|
catCode := tryCatName2Code(storeSku.VendorCatID)
|
||||||
|
if catCode != "" {
|
||||||
|
foodData["category_code"] = catCode
|
||||||
|
} else {
|
||||||
|
foodData["category_name"] = storeSku.VendorCatID
|
||||||
|
}
|
||||||
|
foodData["is_sold_out"] = skuStatusJX2Mtwm(storeSku.MergedStatus)
|
||||||
|
if true { // vendorStoreID == specialStoreID {
|
||||||
|
img2 := storeSku.Img2
|
||||||
|
img3 := storeSku.Img3
|
||||||
|
img4 := storeSku.Img4
|
||||||
|
img5 := storeSku.Img5
|
||||||
|
if img2 == "" {
|
||||||
|
img2 = storeSku.Img
|
||||||
|
}
|
||||||
|
if img3 == "" {
|
||||||
|
img3 = storeSku.Img
|
||||||
|
}
|
||||||
|
if img4 == "" {
|
||||||
|
img4 = storeSku.Img
|
||||||
|
}
|
||||||
|
if img5 == "" {
|
||||||
|
img5 = storeSku.Img
|
||||||
|
}
|
||||||
|
if storeSku.ImgMix != "" && ((storeSku.BrandID == storeSku.ExBrandID && storeSku.ExBrandID != 0) || storeSku.ExBrandID == 0) {
|
||||||
|
foodData["picture"] = strings.Join(jxutils.BatchString2Slice(storeSku.ImgMix, img2, img3, img4, img5), ",")
|
||||||
|
} else {
|
||||||
|
foodData["picture"] = strings.Join(jxutils.BatchString2Slice(storeSku.Img, img2, img3, img4, img5), ",")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foodData["picture"] = strings.Join(jxutils.BatchString2Slice(storeSku.Img, storeSku.Img2), ",")
|
||||||
|
}
|
||||||
|
if storeSku.DescImg != "" {
|
||||||
|
foodData["picture_contents"] = storeSku.DescImg
|
||||||
|
}
|
||||||
|
foodData["sequence"] = storeSku.GetSeq()
|
||||||
|
if storeSku.VendorVendorCatID != 0 {
|
||||||
|
foodData["tag_id"] = utils.Int64ToStr(storeSku.VendorVendorCatID)
|
||||||
|
} else {
|
||||||
|
// foodData["tag_id"] = utils.Int64ToStr(defVendorCatID)
|
||||||
|
}
|
||||||
|
skus[0]["spec"] = jxutils.ComposeSkuSpec(storeSku.SpecQuality, storeSku.SpecUnit)
|
||||||
|
if isNeedUpdatePrice {
|
||||||
|
skus[0]["price"] = foodData["price"]
|
||||||
|
}
|
||||||
|
skus[0]["stock"] = stockCount2Mtwm(model.MaxStoreSkuStockQty)
|
||||||
|
if storeSku.Upc != "" {
|
||||||
|
skus[0]["upc"] = storeSku.Upc
|
||||||
|
}
|
||||||
|
skus[0]["ladder_box_num"] = storeSku.LadderBoxNum
|
||||||
|
boxPirce := 0
|
||||||
|
if storeSku.MtLadderBoxPrice != 0 {
|
||||||
|
boxPirce = storeSku.MtLadderBoxPrice
|
||||||
|
} else {
|
||||||
|
boxPirce = storeSku.LadderBoxPrice
|
||||||
|
}
|
||||||
|
skus[0]["ladder_box_price"] = jxutils.IntPrice2Standard(int64(boxPirce))
|
||||||
|
if foodData["tag_id"] != nil {
|
||||||
|
skus[0]["weight"] = storeSku.Weight // weight字段仅限服饰鞋帽、美妆、日用品、母婴、生鲜果蔬、生活超市下的便利店/超市门店品类的商家使用
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
if len(foodDataList) == 1 {
|
||||||
|
foodDataList[0]["skus"] = string(utils.MustMarshal(foodDataList[0]["skus"]))
|
||||||
|
if err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailInitData(ctx.GetTrackInfo(), vendorStoreID, utils.Int2Str(storeSkuList[0].SkuID), foodDataList[0]); err != nil {
|
||||||
|
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDMTWM], syncType)
|
||||||
|
}
|
||||||
|
} else if len(foodDataList) > 0 {
|
||||||
|
failedFoodList, err2 := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailBatchInitData(ctx.GetTrackInfo(), vendorStoreID, foodDataList)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
if err = putils.GenPartialFailedErr(failedFoodList, len(failedFoodList)); err != nil {
|
||||||
|
failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], syncType)
|
||||||
|
// successList = putils.UnselectStoreSkuSyncListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList))
|
||||||
|
}
|
||||||
|
} else if err2 != nil && len(failedFoodList) == 0 {
|
||||||
|
if errExt, ok := err2.(*utils.ErrorWithCode); ok {
|
||||||
|
err = utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &failedFoodList)
|
||||||
|
failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], syncType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, storeSku := range storeSkuList {
|
||||||
|
storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID)
|
||||||
|
}
|
||||||
|
if len(failedList) > 0 {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
return failedList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAppFoodCodeList(l []*mtwmapi.AppFoodResult) (vendorSkuIDs []string) {
|
||||||
|
if len(l) > 0 {
|
||||||
|
vendorSkuIDs = make([]string, len(l))
|
||||||
|
for k, v := range l {
|
||||||
|
vendorSkuIDs[k] = v.AppFoodCode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vendorSkuIDs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
if len(storeSkuList) == 1 {
|
||||||
|
err = getAPI(storeSkuList[0].VendorOrgCode, storeID, vendorStoreID).RetailDelete(ctx.GetTrackInfo(), vendorStoreID, storeSkuList[0].VendorSkuID)
|
||||||
|
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDMTWM], "删除商品")
|
||||||
|
} else {
|
||||||
|
// todo 部分失败
|
||||||
|
err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, nil, nil, nil, nil, partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDList())
|
||||||
|
if err != nil {
|
||||||
|
if errExt, ok := err.(*utils.ErrorWithCode); ok {
|
||||||
|
myMap := make(map[string][]*mtwmapi.AppFoodResult)
|
||||||
|
json.Unmarshal([]byte(errExt.ErrMsg()), &myMap)
|
||||||
|
failedList = SelectStoreSkuListByFoodList(storeSkuList, myMap["retail_error_list"], storeID, model.VendorChineseNames[model.VendorIDMTWM], "批量删除商品")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(failedList) > 0 {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
return failedList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SwitchAttr(vendorCatID int64) (attrs string) {
|
||||||
|
switch vendorCatID {
|
||||||
|
case 200002727:
|
||||||
|
return mtwmapi.MtwmSkuAttr200002727
|
||||||
|
case 200001555:
|
||||||
|
return mtwmapi.MtwmSkuAttr200001555
|
||||||
|
case 200002728:
|
||||||
|
return mtwmapi.MtwmSkuAttr200002728
|
||||||
|
case 200001519, 200000592:
|
||||||
|
return mtwmapi.MtwmSkuAttr200000592
|
||||||
|
case 200002704, 200002731:
|
||||||
|
return mtwmapi.MtwmSkuAttr200002731
|
||||||
|
case 200002716:
|
||||||
|
return mtwmapi.MtwmSkuAttr200002716
|
||||||
|
case 200002667, 200002713, 200002670:
|
||||||
|
return mtwmapi.MtwmSkuAttr200002670
|
||||||
|
case 200002680:
|
||||||
|
return mtwmapi.MtwmSkuAttr200002680
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return attrs
|
||||||
|
}
|
||||||
|
|
||||||
|
func stockCount2Mtwm(stock int) (mtwmStock string) {
|
||||||
|
return utils.Int2Str(stock)
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeSku2Mtwm(storeSkuList []*partner.StoreSkuInfo, updateType int) (skuList []*mtwmapi.BareStoreFoodInfo) {
|
||||||
|
for _, storeSku := range storeSkuList {
|
||||||
|
skuInfo := &mtwmapi.BareStoreFoodInfo{
|
||||||
|
AppFoodCode: storeSku.VendorSkuID,
|
||||||
|
Skus: []*mtwmapi.BareStoreSkuInfo{
|
||||||
|
&mtwmapi.BareStoreSkuInfo{
|
||||||
|
SkuID: storeSku.VendorSkuID,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if updateType == updateTypeStock {
|
||||||
|
skuInfo.Skus[0].Stock = stockCount2Mtwm(storeSku.Stock)
|
||||||
|
} else if updateType == updateTypePrice {
|
||||||
|
skuInfo.Skus[0].Price = jxutils.IntPrice2StandardString(storeSku.VendorPrice)
|
||||||
|
} else {
|
||||||
|
skuInfo.Skus = nil
|
||||||
|
}
|
||||||
|
skuList = append(skuList, skuInfo)
|
||||||
|
}
|
||||||
|
return skuList
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||||
|
skuList := storeSku2Mtwm(storeSkuList, updateTypeStatus)
|
||||||
|
mtwmStatus := skuStatusJX2Mtwm(status)
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
failedFoodList, err2 := getAPI(vendorOrgCode, storeID, vendorStoreID).RetailSellStatus(ctx.GetTrackInfo(), vendorStoreID, skuList, mtwmStatus)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
if len(failedFoodList) > 0 {
|
||||||
|
failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品状态")
|
||||||
|
// successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList))
|
||||||
|
}
|
||||||
|
} else if err2 != nil && len(failedFoodList) == 0 {
|
||||||
|
if errExt, ok := err2.(*utils.ErrorWithCode); ok {
|
||||||
|
err = utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &failedFoodList)
|
||||||
|
failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品状态")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(failedList) > 0 {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
return failedList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||||
|
priceList := storeSku2Mtwm(storeSkuList, updateTypePrice)
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
failedFoodList, err2 := getAPI(vendorOrgCode, storeID, vendorStoreID).RetailSkuPrice(ctx.GetTrackInfo(), vendorStoreID, priceList)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
if len(failedFoodList) > 0 {
|
||||||
|
failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品价格")
|
||||||
|
}
|
||||||
|
} else if err2 != nil && len(failedFoodList) == 0 {
|
||||||
|
if errExt, ok := err2.(*utils.ErrorWithCode); ok {
|
||||||
|
err = utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &failedFoodList)
|
||||||
|
failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品价格")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(failedList) > 0 {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
return failedList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||||
|
stockList := storeSku2Mtwm(storeSkuList, updateTypeStock)
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
failedFoodList, err2 := getAPI(vendorOrgCode, storeID, vendorStoreID).RetailSkuStock(ctx.GetTrackInfo(), vendorStoreID, stockList)
|
||||||
|
if err = err2; err == nil {
|
||||||
|
if len(failedFoodList) > 0 {
|
||||||
|
failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品库存")
|
||||||
|
}
|
||||||
|
//if err = putils.GenPartialFailedErr(failedFoodList, len(failedFoodList)); err != nil {
|
||||||
|
// successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList))
|
||||||
|
// }
|
||||||
|
} else if err2 != nil && len(failedFoodList) == 0 {
|
||||||
|
if errExt, ok := err2.(*utils.ErrorWithCode); ok {
|
||||||
|
err = utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &failedFoodList)
|
||||||
|
failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品库存")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(failedList) > 0 {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
return failedList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func mtwmSkuStatus2Jx(mtwmSkuStatus int) (jxSkuStatus int) {
|
||||||
|
if mtwmSkuStatus == mtwmapi.SellStatusOnline {
|
||||||
|
jxSkuStatus = model.SkuStatusNormal
|
||||||
|
} else {
|
||||||
|
jxSkuStatus = model.SkuStatusDontSale
|
||||||
|
}
|
||||||
|
return jxSkuStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) {
|
||||||
|
if len(storeSkuList) == 1 {
|
||||||
|
skuInfo, err := getAPI(storeSkuList[0].VendorOrgCode, storeID, vendorStoreID).RetailGet(vendorStoreID, utils.Int2Str(storeSkuList[0].SkuID))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if skuName := vendorSku2Jx(skuInfo); skuName != nil {
|
||||||
|
skuNameList = append(skuNameList, skuName)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var storeSkuMap map[string]*partner.StoreSkuInfo
|
||||||
|
if storeSkuList != nil {
|
||||||
|
storeSkuMap = putils.StoreSkuList2MapByVendorSkuID(storeSkuList)
|
||||||
|
}
|
||||||
|
mtapi := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID)
|
||||||
|
for {
|
||||||
|
// todo 待优化获取速度
|
||||||
|
result, err := mtapi.RetailList(vendorStoreID, len(skuNameList), mtwmapi.GeneralMaxLimit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if storeSkuMap == nil {
|
||||||
|
skuNameList = append(skuNameList, vendorSkuList2Jx(result)...)
|
||||||
|
} else {
|
||||||
|
for _, v := range result {
|
||||||
|
if storeSkuMap[v.AppFoodCode] != nil {
|
||||||
|
if skuName := vendorSku2Jx(v); skuName != nil {
|
||||||
|
skuNameList = append(skuNameList, skuName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(result) < mtwmapi.GeneralMaxLimit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skuNameList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func vendorSku2Jx(appFood *mtwmapi.AppFood) (skuName *partner.SkuNameInfo) {
|
||||||
|
if len(appFood.SkuList) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(appFood.Name)
|
||||||
|
vendorSku := appFood.SkuList[0]
|
||||||
|
weight := int(utils.Str2Int64WithDefault(vendorSku.Weight, 0))
|
||||||
|
if weight <= 0 {
|
||||||
|
weight = jxutils.FormatSkuWeight(specQuality, specUnit)
|
||||||
|
}
|
||||||
|
skuID := int(utils.Str2Int64WithDefault(vendorSku.SkuID, 0))
|
||||||
|
skuName = &partner.SkuNameInfo{
|
||||||
|
NameID: int(utils.Str2Int64WithDefault(appFood.AppFoodCode, 0)),
|
||||||
|
VendorNameID: appFood.AppFoodCode,
|
||||||
|
UPC: appFood.SkuList[0].Upc,
|
||||||
|
Prefix: prefix,
|
||||||
|
Name: name,
|
||||||
|
Unit: unit,
|
||||||
|
Status: mtwmSkuStatus2Jx(appFood.IsSoldOut), //此处为之前一个bug 如果吧状态放到切片内层 对于内层函数中映射无法关联 永远获取到的初始值为0
|
||||||
|
SkuList: []*partner.SkuInfo{
|
||||||
|
&partner.SkuInfo{
|
||||||
|
StoreSkuInfo: partner.StoreSkuInfo{
|
||||||
|
VendorSkuID: vendorSku.SkuID,
|
||||||
|
SkuID: skuID,
|
||||||
|
IsSpecialty: appFood.IsSpecialty,
|
||||||
|
Stock: int(utils.Str2Int64WithDefault(vendorSku.Stock, partner.UnlimitedStoreSkuStock)),
|
||||||
|
VendorPrice: jxutils.StandardPrice2Int(utils.Str2Float64WithDefault(vendorSku.Price, 0)),
|
||||||
|
Status: mtwmSkuStatus2Jx(appFood.IsSoldOut),
|
||||||
|
},
|
||||||
|
SkuName: appFood.Name,
|
||||||
|
Comment: comment,
|
||||||
|
SpecQuality: float64(specQuality),
|
||||||
|
SpecUnit: specUnit,
|
||||||
|
Weight: weight,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PictureList: appFood.PictureList,
|
||||||
|
}
|
||||||
|
if appFood.CategoryName != "" {
|
||||||
|
// todo, 因为当前我们用的是分类名操作这种方式,所以要返回分类名(而不是分类code)
|
||||||
|
skuName.VendorCatIDList = []string{appFood.CategoryName}
|
||||||
|
if appFood.SecondaryCategoryName != "" {
|
||||||
|
skuName.VendorCatIDList = append(skuName.VendorCatIDList, appFood.SecondaryCategoryName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skuName
|
||||||
|
}
|
||||||
|
|
||||||
|
func vendorSkuList2Jx(appFoodList []*mtwmapi.AppFood) (skuNameList []*partner.SkuNameInfo) {
|
||||||
|
for _, appFood := range appFoodList {
|
||||||
|
if skuName := vendorSku2Jx(appFood); skuName != nil {
|
||||||
|
skuNameList = append(skuNameList, skuName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return skuNameList
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp {
|
||||||
|
return sensitiveWordRegexp
|
||||||
|
}
|
||||||
|
|
||||||
|
//美团api返回
|
||||||
|
func SelectStoreSkuListByFoodList(storeSkuList interface{}, foodList []*mtwmapi.AppFoodResult, storeID int, vendorName, syncType string) (selectedStoreSkuList []*partner.StoreSkuInfoWithErr) {
|
||||||
|
foodMap := make(map[string]string)
|
||||||
|
if len(foodList) > 0 {
|
||||||
|
for _, v := range foodList {
|
||||||
|
foodMap[v.AppFoodCode] = v.ErrorMsg
|
||||||
|
}
|
||||||
|
if storeSkuLists, ok := storeSkuList.([]*partner.StoreSkuInfo); ok {
|
||||||
|
for _, v := range storeSkuLists {
|
||||||
|
if foodMap[v.VendorSkuID] != "" {
|
||||||
|
foodFailed := &partner.StoreSkuInfoWithErr{
|
||||||
|
StoreSkuInfo: v,
|
||||||
|
ErrMsg: foodMap[v.VendorSkuID],
|
||||||
|
StoreID: storeID,
|
||||||
|
VendoreName: vendorName,
|
||||||
|
SyncType: syncType,
|
||||||
|
}
|
||||||
|
selectedStoreSkuList = append(selectedStoreSkuList, foodFailed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if storeSkuLists, ok := storeSkuList.([]*dao.StoreSkuSyncInfo); ok {
|
||||||
|
for _, v := range storeSkuLists {
|
||||||
|
if foodMap[v.VendorSkuID] != "" {
|
||||||
|
storeSkuInfo := &partner.StoreSkuInfo{
|
||||||
|
SkuID: v.SkuID,
|
||||||
|
VendorSkuID: v.VendorSkuID,
|
||||||
|
NameID: v.NameID,
|
||||||
|
VendorNameID: v.VendorNameID,
|
||||||
|
VendorPrice: v.VendorPrice,
|
||||||
|
Status: v.Status,
|
||||||
|
}
|
||||||
|
foodFailed := &partner.StoreSkuInfoWithErr{
|
||||||
|
StoreSkuInfo: storeSkuInfo,
|
||||||
|
ErrMsg: foodMap[v.VendorSkuID],
|
||||||
|
StoreID: storeID,
|
||||||
|
VendoreName: vendorName,
|
||||||
|
SyncType: syncType,
|
||||||
|
}
|
||||||
|
selectedStoreSkuList = append(selectedStoreSkuList, foodFailed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selectedStoreSkuList
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) CreateStoreSkusAct(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||||
|
actStoreSkuList := putils.StoreSku2ActStoreSku(model.SyncFlagNewMask, vendorStoreID, storeSkuList)
|
||||||
|
failedList, err = createOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, 0), vendorStoreID, actStoreSkuList)
|
||||||
|
storeSkuMap := putils.StoreSkuList2MapBySkuID(storeSkuList)
|
||||||
|
for _, v := range actStoreSkuList {
|
||||||
|
storeSkuMap[v.SkuID].VendorActID = v.VendorActID
|
||||||
|
}
|
||||||
|
if len(failedList) > 0 {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
return failedList, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) CancelActs(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
|
||||||
|
return cancelOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, 0), vendorStoreID, putils.StoreSku2ActStoreSku(model.SyncFlagDeletedMask, vendorStoreID, storeSkuList))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) UpdateStoreSkusSpecTag(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (err error) {
|
||||||
|
var foodDataList = []map[string]interface{}{}
|
||||||
|
for _, v := range storeSkuList {
|
||||||
|
var foodData = make(map[string]interface{})
|
||||||
|
if v.IsSpecialty == -1 {
|
||||||
|
v.IsSpecialty = 0
|
||||||
|
}
|
||||||
|
foodData["is_specialty"] = v.IsSpecialty
|
||||||
|
foodData["app_food_code"] = v.SkuID
|
||||||
|
foodDataList = append(foodDataList, foodData)
|
||||||
|
}
|
||||||
|
if globals.EnableMtwmStoreWrite {
|
||||||
|
if len(foodDataList) == 1 {
|
||||||
|
err = getAPI(vendorOrgCode, storeID, vendorStoreID).RetailInitData(ctx.GetTrackInfo(), vendorStoreID, utils.Int2Str(storeSkuList[0].SkuID), foodDataList[0])
|
||||||
|
} else if len(foodDataList) > 0 {
|
||||||
|
_, err = getAPI(vendorOrgCode, storeID, vendorStoreID).RetailBatchInitData(ctx.GetTrackInfo(), vendorStoreID, foodDataList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetSkuCategoryIdByName(vendorOrgCode, skuName string) (vendorCategoryId string, err error) {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
64
business/partner/purchase/tao_vegetable/store_sku2_test.go
Normal file
64
business/partner/purchase/tao_vegetable/store_sku2_test.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
// _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetStoreSkusFullInfo(t *testing.T) {
|
||||||
|
skuNameList, err := CurPurchaseHandler.GetStoreSkusFullInfo(jxcontext.AdminCtx, nil, 2, "8967897", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(utils.Format4Output(skuNameList, false))
|
||||||
|
t.Log(len(skuNameList))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetStoreSkusBareInfo(t *testing.T) {
|
||||||
|
storeSkuList, err := CurPurchaseHandler.GetStoreSkusBareInfo(jxcontext.AdminCtx, "", nil, 2, "2523687", []*partner.StoreSkuInfo{
|
||||||
|
&partner.StoreSkuInfo{
|
||||||
|
SkuID: 16205,
|
||||||
|
},
|
||||||
|
//&partner.StoreSkuInfo{
|
||||||
|
// SkuID: 1306,
|
||||||
|
//},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
t.Log(utils.Format4Output(storeSkuList, false))
|
||||||
|
t.Log(len(storeSkuList))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteStoreAllSkus(t *testing.T) {
|
||||||
|
err := CurPurchaseHandler.DeleteStoreAllSkus(jxcontext.AdminCtx, nil, 2, "2523687", true)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteStoreAllCategories(t *testing.T) {
|
||||||
|
err := CurPurchaseHandler.DeleteStoreAllCategories(jxcontext.AdminCtx, nil, 2, "2523687", true)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetStoreCategory(t *testing.T) {
|
||||||
|
_, err := CurPurchaseHandler.GetStoreCategory(jxcontext.AdminCtx, 2, "2523687", "不存在的分类")
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("应该找不到这个分类")
|
||||||
|
}
|
||||||
|
catName := "小月饼"
|
||||||
|
cat, err := CurPurchaseHandler.GetStoreCategory(jxcontext.AdminCtx, 2, "2523687", catName)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if cat.Name != catName {
|
||||||
|
t.Fatal("没有找到正确的商家分类")
|
||||||
|
}
|
||||||
|
t.Log(utils.Format4Output(cat, false))
|
||||||
|
}
|
||||||
46
business/partner/purchase/tao_vegetable/store_sku_test.go
Normal file
46
business/partner/purchase/tao_vegetable/store_sku_test.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||||||
|
// _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
|
||||||
|
)
|
||||||
|
|
||||||
|
// func TestSyncStoreCategory(t *testing.T) {
|
||||||
|
// hint, err := CurPurchaseHandler.SyncStoreCategory(jxcontext.AdminCtx, nil, testShopID, false)
|
||||||
|
// if err != nil {
|
||||||
|
// t.Fatal(err)
|
||||||
|
// }
|
||||||
|
// t.Log(hint)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func TestSyncLocalStoreCategory(t *testing.T) {
|
||||||
|
// hint, err := CurPurchaseHandler.SyncLocalStoreCategory(jxcontext.AdminCtx, nil, testShopID, true, nil)
|
||||||
|
// if err != nil {
|
||||||
|
// t.Fatal(err)
|
||||||
|
// }
|
||||||
|
// t.Log(hint)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func TestSyncStoreSkus(t *testing.T) {
|
||||||
|
// hint, err := CurPurchaseHandler.SyncStoreSkus(jxcontext.AdminCtx, nil, testShopID, nil, false, true)
|
||||||
|
// if err != nil {
|
||||||
|
// t.Fatal(err)
|
||||||
|
// }
|
||||||
|
// t.Log(hint)
|
||||||
|
// }
|
||||||
|
|
||||||
|
func TestDeleteRemoteSkus(t *testing.T) {
|
||||||
|
err := CurPurchaseHandler.DeleteStoreAllSkus(jxcontext.AdminCtx, nil, testShopID, testShopVendorID, true)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteRemoteCategories(t *testing.T) {
|
||||||
|
err := CurPurchaseHandler.DeleteStoreAllCategories(jxcontext.AdminCtx, nil, testShopID, testShopVendorID, true)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
43
business/partner/purchase/tao_vegetable/store_test.go
Normal file
43
business/partner/purchase/tao_vegetable/store_test.go
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
// _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
|
||||||
|
)
|
||||||
|
|
||||||
|
//func TestReadStore(t *testing.T) {
|
||||||
|
// store, err := CurPurchaseHandler.ReadStore(jxcontext.AdminCtx, "", "4351018")
|
||||||
|
// if err != nil {
|
||||||
|
// t.Fatal(err)
|
||||||
|
// }
|
||||||
|
// t.Log(utils.Format4Output(store, false))
|
||||||
|
//}
|
||||||
|
|
||||||
|
func TestUpdateStore(t *testing.T) {
|
||||||
|
err := CurPurchaseHandler.UpdateStore(nil, 100002, "test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConstrainOpTimeList(t *testing.T) {
|
||||||
|
timeList := constrainOpTimeList([]int16{830, 1800}, []int16{
|
||||||
|
0,
|
||||||
|
200,
|
||||||
|
930,
|
||||||
|
1700,
|
||||||
|
})
|
||||||
|
t.Log(utils.Format4Output(timeList, false))
|
||||||
|
if timeList[0] != 930 || timeList[1] != 1700 {
|
||||||
|
t.Fatal("constrainOpTimeList failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetOpTimeListFromErr(t *testing.T) {
|
||||||
|
err := utils.NewErrorIntCode("当前配送营业时间为:07:00~24:00", mtwmapi.ErrCodeOpFailed)
|
||||||
|
list := getOpTimeListFromErr(err)
|
||||||
|
t.Log(list)
|
||||||
|
}
|
||||||
64
business/partner/purchase/tao_vegetable/waybill.go
Normal file
64
business/partner/purchase/tao_vegetable/waybill.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package mtwm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/partner"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
VendorWaybillStatus2StatusMap = map[string]int{
|
||||||
|
mtwmapi.WaybillStatusWait4Delivery: model.WaybillStatusNew,
|
||||||
|
mtwmapi.WaybillStatusPending: model.WaybillStatusPending,
|
||||||
|
mtwmapi.WaybillStatusAccepted: model.WaybillStatusAccepted,
|
||||||
|
mtwmapi.WaybillStatusCourierArrived: model.WaybillStatusCourierArrived,
|
||||||
|
mtwmapi.WaybillStatusPickedup: model.WaybillStatusDelivering,
|
||||||
|
mtwmapi.WaybillStatusDelivered: model.WaybillStatusDelivered,
|
||||||
|
mtwmapi.WaybillStatusCanceled: model.WaybillStatusCanceled,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *PurchaseHandler) GetWaybillStatusFromVendorStatus(vendorStatus string) int {
|
||||||
|
if status, ok := VendorWaybillStatus2StatusMap[vendorStatus]; ok {
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
return model.WaybillStatusUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) onWaybillMsg(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) {
|
||||||
|
waybill := c.callbackMsg2Waybill(msg)
|
||||||
|
err := partner.CurOrderManager.OnWaybillStatusChanged(waybill)
|
||||||
|
if err == nil && waybill.Status == model.WaybillStatusDelivering {
|
||||||
|
c.postFakeMsg(waybill.VendorOrderID, FakeMsgType, mtwmapi.OrderStatusDelivering)
|
||||||
|
}
|
||||||
|
return mtwmapi.Err2CallbackResponse(err, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PurchaseHandler) callbackMsg2Waybill(msg *mtwmapi.CallbackMsg) (retVal *model.Waybill) {
|
||||||
|
orderID := GetOrderIDFromMsg(msg)
|
||||||
|
vendorStatus := msg.FormData.Get("logistics_status")
|
||||||
|
retVal = &model.Waybill{
|
||||||
|
VendorOrderID: orderID,
|
||||||
|
OrderVendorID: model.VendorIDMTWM,
|
||||||
|
VendorWaybillID: orderID,
|
||||||
|
WaybillVendorID: model.VendorIDMTWM,
|
||||||
|
CourierName: msg.FormData.Get("dispatcher_name"),
|
||||||
|
CourierMobile: msg.FormData.Get("dispatcher_mobile"),
|
||||||
|
VendorStatus: vendorStatus,
|
||||||
|
Status: c.GetWaybillStatusFromVendorStatus(vendorStatus),
|
||||||
|
StatusTime: getTimeFromTimestamp(utils.Str2Int64(msg.FormData.Get("time"))),
|
||||||
|
Remark: "",
|
||||||
|
VendorOrgCode: msg.AppID,
|
||||||
|
}
|
||||||
|
if retVal.StatusTime == utils.DefaultTimeValue {
|
||||||
|
retVal.StatusTime = getTimeFromTimestamp(utils.Str2Int64(msg.FormData.Get("timestamp")))
|
||||||
|
}
|
||||||
|
|
||||||
|
//if vendorStatus == "4" || vendorStatus == "8" { // 4:美团推送已经(确认骑手)订单 8:美团推送(骑手完成)订单
|
||||||
|
// retVal.DesiredFee = utils.Float64TwoInt64(utils.Str2Float64WithDefault(msg.FormData.Get("shipping_fee"), 0)) // 订单优惠前的总费用
|
||||||
|
// partner.CurOrderManager
|
||||||
|
//}
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user