2021 lines
77 KiB
Go
2021 lines
77 KiB
Go
package orderman
|
||
|
||
import (
|
||
"crypto/md5"
|
||
"errors"
|
||
"fmt"
|
||
beego "github.com/astaxie/beego/server/web"
|
||
"math"
|
||
"strings"
|
||
"time"
|
||
|
||
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
|
||
"git.rosy.net.cn/baseapi/platformapi/jdeclpapi"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
|
||
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
|
||
"git.rosy.net.cn/jx-callback/business/partner/purchase/jdshop"
|
||
"git.rosy.net.cn/jx-callback/globals/api"
|
||
|
||
"git.rosy.net.cn/baseapi"
|
||
"git.rosy.net.cn/baseapi/platformapi/jdshopapi"
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
"git.rosy.net.cn/jx-callback/business/jxcallback/scheduler"
|
||
"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"
|
||
"github.com/astaxie/beego/client/orm"
|
||
)
|
||
|
||
var (
|
||
orderNoBeginTimestamp int64
|
||
)
|
||
|
||
func init() {
|
||
orderNoBeginTimestamp = utils.Str2Time("2010-01-01 00:00:00").Unix()
|
||
}
|
||
|
||
type tSkuCountPrice struct {
|
||
Count int `json:"count"`
|
||
SalePrice int64 `json:"salePrice"`
|
||
}
|
||
|
||
// msgVendorStatus的意思是事件本身的类型,类似有时收到NewOrder事件去取,订单状态不一定就是New的
|
||
// OnOrderAdjust也类似,而OrderStatus要记录的是消息,所以添加这个
|
||
func (c *OrderManager) OnOrderNew(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) {
|
||
globals.SugarLogger.Debugf("OnOrderNew orderID:%s", order.VendorOrderID)
|
||
if order.ConsigneeMobile2 == "" && jxutils.IsStringLikeMobile(order.ConsigneeMobile) {
|
||
order.ConsigneeMobile2 = order.ConsigneeMobile
|
||
}
|
||
|
||
db := dao.GetDB()
|
||
txDB, _ := dao.Begin(db)
|
||
defer func() {
|
||
globals.SugarLogger.Debugf("OnOrderNew exit orderID:%s", order.VendorOrderID)
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db, txDB)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if order.Status == model.OrderStatusUnknown {
|
||
order.Status = model.OrderStatusNew
|
||
}
|
||
|
||
var isDuplicated bool
|
||
if order.Status == model.OrderStatusNew && order.VendorID == model.VendorIDJX && !model.IsOrderJXTemp(order) {
|
||
isDuplicated, _, err = c.addOrderStatus(orderStatus, db)
|
||
} else {
|
||
isDuplicated, err = addOrderOrWaybillStatus(orderStatus, db)
|
||
if err == nil && !isDuplicated {
|
||
isDuplicated, err = c.SaveOrder(order, false, db)
|
||
}
|
||
}
|
||
if err == nil {
|
||
dao.Commit(db, txDB)
|
||
if !isDuplicated {
|
||
err = scheduler.CurrentScheduler.OnOrderNew(order, false, false)
|
||
}
|
||
} else {
|
||
dao.Rollback(db, txDB)
|
||
}
|
||
return err
|
||
}
|
||
|
||
// todo 调整单的处理可能还需要再细化一点,当前只是简单的删除重建
|
||
func (c *OrderManager) OnOrderAdjust(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) {
|
||
globals.SugarLogger.Debugf("OnOrderAdjust orderID:%s, status:%d", order.VendorOrderID, order.Status)
|
||
if order.ConsigneeMobile2 == "" && jxutils.IsStringLikeMobile(order.ConsigneeMobile) {
|
||
order.ConsigneeMobile2 = order.ConsigneeMobile
|
||
}
|
||
|
||
db := dao.GetDB()
|
||
txDB, _ := dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db, txDB)
|
||
panic(r)
|
||
}
|
||
}()
|
||
// 出现过调整单后,状态回到新订单状态,比如:911350836000622
|
||
// 不完全确定,加一个处理
|
||
if order.Status < model.OrderStatusAccepted {
|
||
order.Status = model.OrderStatusAccepted
|
||
}
|
||
isDuplicated, err := addOrderOrWaybillStatus(orderStatus, db)
|
||
if err == nil && !isDuplicated {
|
||
err = utils.CallFuncLogError(func() error {
|
||
_, err = db.Db.Raw("DELETE FROM order_sku WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID).Exec()
|
||
return err
|
||
}, "OnAdjustOrder delete order, orderID:%s", order.VendorOrderID)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
adjustCount := int8(0)
|
||
previousOrder := &model.GoodsOrder{
|
||
VendorOrderID: order.VendorOrderID,
|
||
VendorID: order.VendorID,
|
||
}
|
||
if err = dao.GetEntity(db, previousOrder, model.FieldVendorOrderID, model.FieldVendorID); err != nil && !dao.IsNoRowsError(err) {
|
||
globals.SugarLogger.Warnf("OnOrderAdjust, order:%s GetEntity failed with error:%v", order.VendorOrderID, err)
|
||
return err
|
||
}
|
||
if err == nil {
|
||
adjustCount = previousOrder.AdjustCount
|
||
if _, err = dao.DeleteEntity(db, previousOrder); err != nil {
|
||
return err
|
||
}
|
||
order.VendorWaybillID = previousOrder.VendorWaybillID
|
||
order.WaybillVendorID = previousOrder.WaybillVendorID
|
||
} else {
|
||
globals.SugarLogger.Warnf("OnOrderAdjust, but previous order:%s doesn't exist", order.VendorOrderID)
|
||
}
|
||
// err = utils.CallFuncLogError(func() error {
|
||
// _, err = db.Db.Raw("DELETE FROM goods_order WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID).Exec()
|
||
// return err
|
||
// }, "OnAdjustOrder delete order_sku, orderID:%s", order.VendorOrderID)
|
||
order.AdjustCount = adjustCount + 1
|
||
//扣点的订单需要修改订单的totalshopmoney
|
||
if err == nil && order.OrderPayPercentage < 50 && order.OrderPayPercentage > 0 {
|
||
order2, _ := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).GetOrder(order.VendorOrgCode, order.VendorOrderID, order.VendorStoreID)
|
||
order.TotalShopMoney = order2.TotalShopMoney
|
||
}
|
||
isDuplicated, err = c.SaveOrder(order, true, db)
|
||
}
|
||
if err == nil {
|
||
dao.Commit(db, txDB)
|
||
if !isDuplicated {
|
||
// 因为订单调度器需要的是真实状态,所以用order的状态
|
||
_ = scheduler.CurrentScheduler.OnOrderNew(order, false, false)
|
||
_ = scheduler.CurrentScheduler.OnOrderStatusChanged(order, orderStatus, false)
|
||
}
|
||
} else {
|
||
dao.Rollback(db, txDB)
|
||
}
|
||
return err
|
||
}
|
||
|
||
func (c *OrderManager) OnOrderStatusChanged(vendorOrgCode string, orderStatus *model.OrderStatus) (err error) {
|
||
// 有些平台(比如美团外卖),在新订单事件没有成功返回,但在重发订单消息前,订单状态转换,则不会再重发新订单事件,特殊处理一下
|
||
if orderStatus != nil {
|
||
if orderStatus.Status == model.OrderStatusAccepted {
|
||
if _, err2 := c.LoadOrder(orderStatus.VendorOrderID, orderStatus.VendorID); err2 == ErrCanNotFindOrder {
|
||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(orderStatus.VendorID); handler != nil {
|
||
if order, err2 := handler.GetOrder(vendorOrgCode, orderStatus.VendorOrderID, ""); err2 == nil {
|
||
c.OnOrderNew(order, orderStatus)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
db := dao.GetDB()
|
||
txDB, _ := dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db, txDB)
|
||
panic(r)
|
||
}
|
||
}()
|
||
isDuplicated, order, err := c.addOrderStatus(orderStatus, db)
|
||
if err == nil {
|
||
dao.Commit(db, txDB)
|
||
if orderStatus.Status == model.OrderStatusWaybillTipChanged {
|
||
if order, err2 := c.LoadOrder(orderStatus.VendorOrderID, orderStatus.VendorID); err2 == nil {
|
||
if handler := partner.GetWaybillTipUpdater(orderStatus.RefVendorID); handler != nil {
|
||
tipFee, err2 := handler.GetWaybillTip(jxcontext.AdminCtx, vendorOrgCode, order.VendorStoreID, orderStatus.RefVendorOrderID, orderStatus.VendorOrderID, "")
|
||
if err2 == nil {
|
||
order.WaybillTipMoney = tipFee
|
||
c.UpdateOrderFields(order, []string{"WaybillTipMoney"})
|
||
}
|
||
}
|
||
}
|
||
} else if orderStatus.Status == model.OrderStatusFinished {
|
||
if order, err2 := c.LoadOrder(orderStatus.VendorOrderID, orderStatus.VendorID); err2 == nil {
|
||
// 当前只针对三方运单更新配送费信息
|
||
if order.WaybillVendorID >= 0 && order.VendorWaybillID != "" && order.WaybillVendorID != order.VendorID {
|
||
if waybill, err2 := c.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID); err2 == nil {
|
||
if handler := partner.GetWaybillTipUpdater(waybill.WaybillVendorID); handler != nil {
|
||
tipFee, err2 := handler.GetWaybillTip(jxcontext.AdminCtx, waybill.VendorOrgCode, "", order.VendorOrderID, waybill.VendorWaybillID, waybill.VendorWaybillID2)
|
||
if err2 == nil && waybill.TipFee != tipFee {
|
||
waybill.ActualFee += tipFee - waybill.TipFee
|
||
waybill.TipFee = tipFee
|
||
dao.UpdateEntity(db, waybill, "TipFee", "ActualFee")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//更新订单new_earning_price
|
||
if order.EarningType == model.EarningTypePoints {
|
||
waybill, _ := c.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID)
|
||
// store, _ := c.LoadStoreDetail(jxutils.GetSaleStoreIDFromOrder(order), order.VendorID)
|
||
if waybill == nil {
|
||
if (order.NewEarningPrice == 0 || order.NewEarningPrice != order.TotalShopMoney*int64(100-order.OrderPayPercentage/2)/int64(100)) && order.OrderPayPercentage <= 50 {
|
||
order.NewEarningPrice = order.TotalShopMoney * int64(100-order.OrderPayPercentage/2) / int64(100)
|
||
}
|
||
} else {
|
||
if (order.NewEarningPrice == 0 || order.NewEarningPrice != (order.TotalShopMoney-waybill.DesiredFee)*int64(100-order.OrderPayPercentage/2)/int64(100)) && order.OrderPayPercentage <= 50 {
|
||
order.NewEarningPrice = order.TotalShopMoney*int64(100-order.OrderPayPercentage/2)/int64(100) - waybill.DesiredFee
|
||
}
|
||
}
|
||
dao.UpdateEntity(db, order, "NewEarningPrice")
|
||
}
|
||
}
|
||
} else if orderStatus.Status == model.OrderStatusCanceled {
|
||
//如果取消订单则要把库存加回去
|
||
if order, err2 := c.LoadOrder(orderStatus.VendorOrderID, orderStatus.VendorID); err2 == nil {
|
||
ModifyOrderSkusStock(db, order, true)
|
||
//门店发单的订单,取消后要退回配送费
|
||
resetCreateWaybillFee(db, order)
|
||
}
|
||
}
|
||
if !isDuplicated {
|
||
if order != nil {
|
||
order.Skus = c.loadOrderSku(db, order.VendorOrderID, order.VendorID)
|
||
_ = scheduler.CurrentScheduler.OnOrderStatusChanged(order, orderStatus, false)
|
||
}
|
||
}
|
||
} else {
|
||
dao.Rollback(db, txDB)
|
||
}
|
||
return err
|
||
}
|
||
|
||
func (c *OrderManager) ChangeOrderInfo(order *model.GoodsOrder) (err error) {
|
||
db := dao.GetDB()
|
||
_, err = dao.UpdateEntity(db, order, "ConsigneeAddress", "ConsigneeName", "ConsigneeMobile", "ConsigneeLat", "ConsigneeLng", "BuyerComment")
|
||
return err
|
||
}
|
||
|
||
func (c *OrderManager) OnOrderMsg(order *model.GoodsOrder, vendorStatus, remark string) (err error) {
|
||
_, _, err = c.addOrderStatus(&model.OrderStatus{
|
||
VendorOrderID: order.VendorOrderID,
|
||
VendorID: order.VendorID,
|
||
OrderType: model.OrderTypeOrder,
|
||
RefVendorOrderID: order.VendorOrderID,
|
||
RefVendorID: order.VendorID,
|
||
|
||
VendorStatus: vendorStatus,
|
||
Status: model.OrderStatusMsg,
|
||
StatusTime: time.Now(),
|
||
Remark: utils.LimitUTF8StringLen(remark, 255),
|
||
}, nil)
|
||
return err
|
||
}
|
||
|
||
func setFakeOrderFlag(db *dao.DaoDB, order *model.GoodsOrder) {
|
||
if order.DeliveryType == model.OrderDeliveryTypeSelfTake {
|
||
if realMobile := jxutils.GetRealMobile4Order(order); realMobile != "" {
|
||
if configList, err := dao.QueryConfigs(db, model.ConfigSysFakeOrderMobiles, model.ConfigTypeSys, ""); err == nil && len(configList) > 0 {
|
||
isMatch := false
|
||
mobileList := strings.Split(configList[0].Value, ",")
|
||
for _, v := range mobileList {
|
||
if jxutils.TrimDecorationChar(v) == realMobile {
|
||
isMatch = true
|
||
break
|
||
}
|
||
}
|
||
if isMatch {
|
||
order.Flag |= model.OrderFlagMaskFake
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
func (c *OrderManager) SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao.DaoDB) (isDuplicated bool, err error) {
|
||
globals.SugarLogger.Debugf("SaveOrder orderID:%s, VendorStoreID:%s, status:%d", order.VendorOrderID, order.VendorStoreID, order.Status)
|
||
// 忽略美团超市的订单
|
||
if order.VendorID == model.VendorIDMTWM {
|
||
if order.VendorStoreID == "2391979" || order.VendorStoreID == "7379027" {
|
||
return
|
||
}
|
||
}
|
||
// 忽略查找JX信息错误
|
||
c.updateOrderOtherInfo(order, db)
|
||
order.ID = 0
|
||
order.WaybillVendorID = model.VendorIDUnknown
|
||
order.OrderFinishedAt = utils.DefaultTimeValue
|
||
|
||
setFakeOrderFlag(db, order)
|
||
// cms.HandleOrder4Consignee(order)
|
||
|
||
txDB, _ := dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil || err != nil {
|
||
dao.Rollback(db, txDB)
|
||
if r != nil {
|
||
panic(r)
|
||
}
|
||
}
|
||
}()
|
||
// todo hardcode 兼容京东消息错序问题
|
||
if true { //order.VendorID == model.VendorIDJD {
|
||
orderStatus := &model.OrderStatus{}
|
||
if dao.GetRow(db, orderStatus, `
|
||
SELECT *
|
||
FROM order_status
|
||
WHERE order_type = ? AND vendor_order_id = ? AND vendor_id = ? AND status > 0
|
||
ORDER BY status_time DESC
|
||
LIMIT 1
|
||
`, model.OrderTypeOrder, order.VendorOrderID, order.VendorID) == nil {
|
||
if orderStatus.Status > order.Status {
|
||
order.Status = orderStatus.Status
|
||
order.VendorStatus = orderStatus.VendorStatus
|
||
order.StatusTime = orderStatus.StatusTime
|
||
|
||
// jxutils.RefreshOrderSkuRelated(order)
|
||
}
|
||
}
|
||
}
|
||
|
||
filterOrderInfo(order)
|
||
created, _, err2 := db.Db.ReadOrCreate(order, "VendorOrderID", "VendorID")
|
||
if err = err2; err == nil {
|
||
originalOrder := &model.GoodsOrderOriginal{
|
||
VendorOrderID: order.VendorOrderID,
|
||
VendorID: order.VendorID,
|
||
OrderCreatedAt: order.OrderCreatedAt,
|
||
OriginalData: order.OriginalData,
|
||
}
|
||
if _, _, err = db.Db.ReadOrCreate(originalOrder, "VendorOrderID", "VendorID"); err == nil {
|
||
if created {
|
||
if err = dao.CreateMultiEntities(db, order.Skus); err != nil {
|
||
baseapi.SugarLogger.Warnf("saveOrder orderID:%s, save order_sku failed with error:%v", order.VendorOrderID, err)
|
||
}
|
||
} else {
|
||
isDuplicated = true
|
||
order.DuplicatedCount++
|
||
db.Db.Update(order, "DuplicatedCount")
|
||
baseapi.SugarLogger.Infof("saveOrder duplicated orderid:%s msg received", order.VendorOrderID)
|
||
}
|
||
}
|
||
} else {
|
||
//globals.SugarLogger.Warnf("saveOrder create order:%v, error:%v", order, err)
|
||
}
|
||
//修改商品库存
|
||
if err == nil {
|
||
err = ModifyOrderSkusStock(db, order, false)
|
||
}
|
||
if err == nil {
|
||
dao.Commit(db, txDB)
|
||
}
|
||
return isDuplicated, err
|
||
}
|
||
|
||
func ModifyOrderSkusStock(db *dao.DaoDB, order *model.GoodsOrder, isAdd bool) (err error) {
|
||
skus := order.Skus
|
||
for _, sku := range skus {
|
||
storeSkus, _ := dao.GetStoresSkusInfo(db, []int{jxutils.GetSaleStoreIDFromOrder(order)}, []int{sku.SkuID})
|
||
if len(storeSkus) == 0 {
|
||
// if !isAdd {
|
||
// globals.SugarLogger.Warnf("此订单商品没得storsku,%v,%v", order.VendorOrderID, sku.SkuID)
|
||
// }
|
||
continue
|
||
}
|
||
storeSku, stock := storeSkus[0], 0
|
||
if storeSku.Stock == 0 {
|
||
if !isAdd {
|
||
// globals.SugarLogger.Warnf("此订单商品库存为0,%v,%v", order.VendorOrderID, sku.SkuID)
|
||
}
|
||
continue
|
||
}
|
||
if isAdd {
|
||
stock = storeSku.Stock + sku.Count
|
||
} else {
|
||
stock = storeSku.Stock - sku.Count
|
||
//如果是进货的订单,进货方门店对应商品要加上这么多库存
|
||
if order.OrderType == model.OrderTypeSupplyGoods {
|
||
storeSkus2, _ := dao.GetStoresSkusInfo(db, []int{order.FromStoreID}, []int{sku.SkuID})
|
||
if len(storeSkus2) > 0 {
|
||
storeSku3 := storeSkus2[0]
|
||
storeSku3.Stock = storeSku3.Stock + sku.Count
|
||
db.Db.Update(storeSku3, "Stock")
|
||
}
|
||
}
|
||
realStock := checkPriceDefendOrderByStock(db, jxutils.GetSaleStoreIDFromOrder(order), sku.SkuID, stock, storeSku.JxPrice)
|
||
if realStock != -1 {
|
||
stock = realStock
|
||
}
|
||
}
|
||
storeSku.Stock = stock
|
||
db.Db.Update(storeSku, "Stock")
|
||
if order.VendorID != model.VendorIDJX {
|
||
// dao.SetStoreSkuSyncStatus(db, order.VendorID, []int{jxutils.GetSaleStoreIDFromOrder(order)}, []int{sku.SkuID}, model.SyncFlagStockMask)
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func filterOrderInfo(order *model.GoodsOrder) {
|
||
order.ConsigneeName = utils.LimitUTF8StringLen2(order.ConsigneeName, 32)
|
||
order.ConsigneeAddress = utils.LimitUTF8StringLen2(order.ConsigneeAddress, 255)
|
||
order.ConsigneeAddress = strings.ReplaceAll(order.ConsigneeAddress, "·", "")
|
||
}
|
||
|
||
func resetCreateWaybillFee(db *dao.DaoDB, order *model.GoodsOrder) (err error) {
|
||
store, _ := dao.GetStoreDetail(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorID, order.VendorOrgCode)
|
||
if store != nil && store.CreateDeliveryType == model.YES {
|
||
if expend, lastFee, err := partner.CurStoreAcctManager.GetStoreAcctExpendLastCreateWayBillFee(order.VendorOrderID); err == nil && expend != nil {
|
||
partner.CurStoreAcctManager.InsertStoreAcctIncomeAndUpdateStoreAcctBalance(jxcontext.AdminCtx, jxutils.GetSaleStoreIDFromOrder(order), lastFee, partner.StoreAcctTypeIncomeCancelReal, order.VendorOrderID, expend.ID)
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func checkPriceDefendOrderByStock(db *dao.DaoDB, storeID, skuID, stock, jxPrice int) (realStock int) {
|
||
var (
|
||
sumStock = 0
|
||
)
|
||
priceDefends, _ := dao.GetPriceDefendOrder(db, "", []int{storeID}, []int{skuID}, []int{jxutils.GetDefendPriceIssue()}, 0, 1, 0, 1, "", utils.ZeroTimeValue, utils.ZeroTimeValue, false)
|
||
if len(priceDefends) == 0 {
|
||
return -1
|
||
}
|
||
for _, v := range priceDefends {
|
||
sumStock += v.Count
|
||
}
|
||
//如果现库存小于等于用户守价的库存,就要开始了
|
||
//如果小于,要按照守价时间的先后来决定
|
||
//如果等于,就刚好全部成功,然后库存清0
|
||
if stock < sumStock {
|
||
tStock := stock
|
||
for _, v := range priceDefends {
|
||
if tStock <= v.Count {
|
||
tStock -= v.Count
|
||
v.IsSuccess = model.YES
|
||
v.RealPrice = int64(jxPrice)
|
||
dao.UpdateEntity(db, v, "IsSuccess", "RealPrice")
|
||
} else {
|
||
continue
|
||
}
|
||
}
|
||
realStock = tStock
|
||
} else if stock == sumStock {
|
||
for _, v := range priceDefends {
|
||
v.IsSuccess = model.YES
|
||
v.RealPrice = int64(jxPrice)
|
||
dao.UpdateEntity(db, v, "IsSuccess", "RealPrice")
|
||
}
|
||
realStock = 0 //库存清0
|
||
} else {
|
||
realStock = -1
|
||
}
|
||
return realStock
|
||
}
|
||
|
||
func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.DaoDB, storePayPercentage, changePriceType int) (err error) {
|
||
globals.SugarLogger.Debugf("updateOrderSkuOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID)
|
||
jxStoreID := jxutils.GetShowStoreIDFromOrder(order)
|
||
var opNumStr string
|
||
if time.Now().Sub(order.OrderCreatedAt) < 1*time.Hour && order.VendorID != model.VendorIDJD {
|
||
opNumStr = "2"
|
||
} else {
|
||
opNumStr = "2"
|
||
}
|
||
|
||
if jxStoreID == 0 {
|
||
return nil
|
||
}
|
||
orderSkus := order.Skus
|
||
|
||
var vendorSkuIDs []string
|
||
for _, v := range orderSkus {
|
||
if v.VendorSkuID != "" {
|
||
vendorSkuIDs = append(vendorSkuIDs, v.VendorSkuID)
|
||
}
|
||
}
|
||
if len(vendorSkuIDs) > 0 {
|
||
var vendorStoreID string
|
||
if order.VendorID == model.VendorIDJDShop && order.VendorOrgCode == "1" {
|
||
vendorStoreID = model.JdShopMainVendorStoreID
|
||
} else {
|
||
vendorStoreID = order.VendorStoreID
|
||
}
|
||
l, err := dao.GetStoreSkuPriceAndWeight(db, vendorStoreID, order.VendorID, vendorSkuIDs)
|
||
if err != nil {
|
||
globals.SugarLogger.Warnf("updateOrderSkuOtherInfo orderID:%s failed with err:%v", order.VendorOrderID, err)
|
||
return err
|
||
}
|
||
skumapper := storeSkuPriceAndWeight2Map(l)
|
||
for _, v := range orderSkus {
|
||
v.VendorOrderID = order.VendorOrderID
|
||
v.VendorID = order.VendorID
|
||
|
||
intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0)
|
||
if intVendorSkuID != 0 && v.VendorSkuID != "-70000" { // todo hard code
|
||
skuBindInfo := skumapper[v.VendorSkuID]
|
||
if skuBindInfo == nil {
|
||
if v.ShopPrice == 0 {
|
||
v.ShopPrice = v.SalePrice * 70 / 100
|
||
}
|
||
globals.SugarLogger.Infof("updateOrderSkuOtherInfo [运营%s]%s订单sku找不到门店价格(或商品映射),orderID:%s, StoreID:%d, VendorSkuID:%s, sku:%v", opNumStr, model.VendorChineseNames[order.VendorID], order.VendorOrderID, jxStoreID, v.VendorSkuID, v)
|
||
} else {
|
||
// TODO 客户端当前逻辑认为SkuID为0为赠品
|
||
if v.SkuID == 0 {
|
||
v.SkuID = v.JxSkuID
|
||
}
|
||
v.JxSkuID = skuBindInfo.SkuID
|
||
//京东商城的话,门店里可能取不到对应商品
|
||
if order.VendorID == model.VendorIDJDShop {
|
||
if v.SkuID == 0 && v.JxSkuID != 0 {
|
||
v.SkuID = v.JxSkuID
|
||
}
|
||
// v.JxSkuID = v.SkuID
|
||
storeSkus, _ := dao.GetStoresSkusInfo(db, []int{order.StoreID}, []int{v.SkuID})
|
||
if len(storeSkus) > 0 {
|
||
v.ShopPrice = int64(storeSkus[0].Price)
|
||
} else {
|
||
v.ShopPrice = v.SalePrice * 70 / 100
|
||
}
|
||
} else {
|
||
v.ShopPrice = int64(skuBindInfo.Price)
|
||
if v.ShopPrice == 0 {
|
||
v.ShopPrice = v.SalePrice * 70 / 100
|
||
}
|
||
}
|
||
v.SkuName = jxutils.ComposeSkuNameOriginal(skuBindInfo.Prefix, skuBindInfo.Name, skuBindInfo.Comment, skuBindInfo.Unit, skuBindInfo.SpecQuality, skuBindInfo.SpecUnit, 0)
|
||
v.Weight = skuBindInfo.Weight // 以本地信息中的WEIGHT为准
|
||
//饿鲜达的订单做一下处理
|
||
if strings.Contains(order.StoreName, model.ExdStoreName) {
|
||
if v.SkuID == 0 && !strings.Contains(v.SkuName, "免费") {
|
||
v.SkuID = v.JxSkuID
|
||
}
|
||
}
|
||
if skuBindInfo.Price == 0 {
|
||
globals.SugarLogger.Infof("updateOrderSkuOtherInfo [运营%s]%s订单sku门店价格为零(一般原因为没有门店价格信息),orderID:%s, StoreID:%d, SkuID:%d, sku:%v", opNumStr, model.VendorChineseNames[order.VendorID], order.VendorOrderID, jxStoreID, v.JxSkuID, v)
|
||
}
|
||
}
|
||
}
|
||
// 直营店始终按比例结算,不考虑活动与结算表
|
||
salePrice := v.SalePrice
|
||
if changePriceType == model.StoreChangePriceTypeManagedStore && v.ShopPrice != 0 {
|
||
salePrice = 0
|
||
}
|
||
v.EarningPrice = jxutils.CaculateSkuEarningPrice(v.ShopPrice, salePrice, storePayPercentage)
|
||
}
|
||
// 直营店始终按比例结算,不考虑活动与结算表
|
||
if changePriceType != model.StoreChangePriceTypeManagedStore {
|
||
updateSingleOrderEarningPrice(order, db)
|
||
}
|
||
//TODO 重复购买有活动且结算价大于0的商品需要拆分,第一个商品按结算价,后面的商品按shopprice 或者 saleprice, 2020-05-06
|
||
//TODO 京东美团的订单,做活动的商品之前就会拆分出来,所以只做更新,饿百暂时不管, 2020-05-07
|
||
//TODO 不根据商品是否拆分,直接根据该商品做了活动,并且他的vendorPrice 和 salePrice 相等,就按新规则结算, 2020-05-11
|
||
//TODO 现在不判断商品做没做活动,只要vendorPrice和salePrice不等,就默认为做了活动,不做活动的商品就按新规则结算,2020-05-18
|
||
// if order.VendorID == model.VendorIDJD || order.VendorID == model.VendorIDMTWM {
|
||
// for _, v := range orderSkus {
|
||
// if v.EarningPrice > 0 {
|
||
// if v.VendorPrice == v.SalePrice {
|
||
// var earningPrice = 0
|
||
// if v.ShopPrice < v.SalePrice {
|
||
// if v.ShopPrice == 0 {
|
||
// earningPrice = int(utils.Float64TwoInt64(math.Round(utils.Int2Float64(int(v.SalePrice)) * utils.Int2Float64(storePayPercentage) / 100)))
|
||
// } else {
|
||
// earningPrice = int(utils.Float64TwoInt64(math.Round(utils.Int2Float64(int(v.ShopPrice)) * utils.Int2Float64(storePayPercentage) / 100)))
|
||
// }
|
||
// } else {
|
||
// earningPrice = int(utils.Float64TwoInt64(math.Round(utils.Int2Float64(int(v.SalePrice)) * utils.Int2Float64(storePayPercentage) / 100)))
|
||
// }
|
||
// v.EarningPrice = int64(earningPrice)
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func storeSkuPriceAndWeight2Map(l []*dao.StoreSkuPriceAndWeight) (skuMapper map[string]*dao.StoreSkuPriceAndWeight) {
|
||
skuMapper = make(map[string]*dao.StoreSkuPriceAndWeight)
|
||
for _, v := range l {
|
||
skuMapper[v.VendorSkuID] = v
|
||
}
|
||
return skuMapper
|
||
}
|
||
|
||
func updateSingleOrderEarningPrice(order *model.GoodsOrder, db *dao.DaoDB) {
|
||
jxStoreID := jxutils.GetShowStoreIDFromOrder(order)
|
||
skuIDMap := make(map[int]int)
|
||
for _, v := range order.Skus {
|
||
if skuID := jxutils.GetSkuIDFromOrderSku(v); skuID > 0 {
|
||
skuIDMap[skuID] = 1
|
||
}
|
||
}
|
||
if len(skuIDMap) > 0 {
|
||
actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, []int{order.VendorID}, model.ActTypeAll, []int{jxStoreID}, jxutils.IntMap2List(skuIDMap), order.OrderCreatedAt, order.OrderCreatedAt)
|
||
if err != nil {
|
||
globals.SugarLogger.Errorf("updateOrderSkuOtherInfo can not get sku promotion info for error:%v", err)
|
||
}
|
||
if actStoreSkuMap := jxutils.NewActStoreSkuMap(actStoreSkuList, false); actStoreSkuMap != nil {
|
||
for _, v := range order.Skus {
|
||
if skuID := jxutils.GetSkuIDFromOrderSku(v); skuID > 0 {
|
||
if actStoreSku := actStoreSkuMap.GetActStoreSku(jxStoreID, skuID, order.VendorID); actStoreSku != nil {
|
||
v.EarningPrice = actStoreSku.EarningPrice
|
||
if true { //v.StoreSubName != "" { // 之前这里为什么要加判断?
|
||
v.StoreSubID = actStoreSku.ActID
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
func (c *OrderManager) updateOrderOtherInfo(order *model.GoodsOrder, db *dao.DaoDB) (err error) {
|
||
globals.SugarLogger.Debugf("updateOrderOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID)
|
||
|
||
payPercentage := 0
|
||
changePriceType := model.StoreChangePriceTypeDirect
|
||
var storeDetail *dao.StoreDetail
|
||
if order.VendorID == model.VendorIDJDShop {
|
||
storeDetail, err = dao.GetStoreDetailByVendorStoreID(db, order.VendorStoreID, order.VendorID, order.VendorOrgCode)
|
||
} else {
|
||
storeDetail, err = dao.GetStoreDetailByVendorStoreID(db, order.VendorStoreID, order.VendorID, "")
|
||
}
|
||
if err != nil {
|
||
if !dao.IsNoRowsError(err) {
|
||
globals.SugarLogger.Warnf("updateOrderOtherInfo GetStoreDetailByVendorStoreID orderID:%s, VendorStoreID:%s, error:%v", order.VendorOrderID, order.VendorStoreID, err)
|
||
return err
|
||
}
|
||
if time.Now().Sub(order.OrderCreatedAt) < 1*time.Hour {
|
||
globals.SugarLogger.Infof("updateOrderOtherInfo [运营]订单在京西与平台都找不到京西门店信息,订单:%s,平台门店ID:%s,平台:%s", order.VendorOrderID, order.VendorStoreID, model.VendorChineseNames[order.VendorID])
|
||
}
|
||
err = nil
|
||
} else {
|
||
order.JxStoreID = storeDetail.Store.ID
|
||
changePriceType = int(storeDetail.ChangePriceType)
|
||
//判断订单结算比例
|
||
if storeDetail.VendorPayPercentage != 0 {
|
||
payPercentage = storeDetail.VendorPayPercentage
|
||
} else {
|
||
payPercentage = storeDetail.PayPercentage
|
||
}
|
||
if payPercentage < 50 {
|
||
order.EarningType = model.EarningTypePoints
|
||
} else {
|
||
order.EarningType = model.EarningTypeQuote
|
||
}
|
||
order.OrderPayPercentage = payPercentage
|
||
order.CreateDeliveryType = storeDetail.CreateDeliveryType
|
||
}
|
||
if err = c.updateOrderSkuOtherInfo(order, db, payPercentage, changePriceType); err == nil {
|
||
jxutils.RefreshOrderSkuRelated(order)
|
||
//EarningPrice2, 新规则,门店结算比例在50以下的做新规则计算
|
||
jxutils.RefreshOrderEarningPrice2(order, payPercentage)
|
||
// caculateOrderEarningPrice(order, payPercentage)
|
||
}
|
||
return err
|
||
}
|
||
|
||
// 计算结算给门店的金额
|
||
// func caculateOrderEarningPrice(order *model.GoodsOrder, storePayPercentage int) {
|
||
// order.EarningPrice = 0
|
||
// for _, v := range order.Skus {
|
||
// skuEarningPrice := v.EarningPrice
|
||
// if skuEarningPrice == 0 {
|
||
// skuEarningPrice = jxutils.CaculateSkuEarningPrice(v.ShopPrice, v.SalePrice, storePayPercentage)
|
||
// }
|
||
// order.EarningPrice += skuEarningPrice * int64(v.Count)
|
||
// }
|
||
// }
|
||
|
||
func (c *OrderManager) addOrderStatus(orderStatus *model.OrderStatus, db *dao.DaoDB) (isDuplicated bool, order *model.GoodsOrder, err error) {
|
||
globals.SugarLogger.Debugf("addOrderStatus refOrderID:%s, orderID:%s", orderStatus.RefVendorOrderID, orderStatus.VendorOrderID)
|
||
if db == nil {
|
||
db = dao.GetDB()
|
||
}
|
||
isDuplicated, err = addOrderOrWaybillStatus(orderStatus, db)
|
||
if err == nil && !isDuplicated && (orderStatus.Status != model.OrderStatusUnknown && orderStatus.Status != model.OrderStatusMsg) {
|
||
order = &model.GoodsOrder{
|
||
VendorOrderID: orderStatus.VendorOrderID,
|
||
VendorID: orderStatus.VendorID,
|
||
}
|
||
if err = db.Db.ReadForUpdate(order, "VendorOrderID", "VendorID"); err == nil {
|
||
// todo 美团在订单完成后,还可能收到订单取消(应该当成售后单处理才合适),强制忽略这种情况,比如订单:80662201436073600
|
||
// 后来又发现有订单(81710104014426376)在完成后,直接再被取消的情况,不能生成售后单,还是再允许完成后取消。。。
|
||
// if orderStatus.VendorID == model.VendorIDMTWM && model.IsOrderFinalStatus(order.Status) {
|
||
// return false, order, nil
|
||
// }
|
||
if (model.IsOrderLockStatus(orderStatus.Status) || model.IsOrderUnlockStatus(orderStatus.Status)) ||
|
||
(model.IsOrderMainStatus(orderStatus.Status) && orderStatus.Status >= order.Status) { // todo 要求status不能回绕
|
||
order.VendorStatus = orderStatus.VendorStatus
|
||
updateFields := []string{
|
||
"VendorStatus",
|
||
"UpdatedAt",
|
||
}
|
||
if model.IsOrderMainStatus(orderStatus.Status) {
|
||
order.Status = orderStatus.Status
|
||
order.StatusTime = orderStatus.StatusTime
|
||
updateFields = append(updateFields, "Status", "StatusTime")
|
||
if model.IsOrderFinalStatus(orderStatus.Status) {
|
||
order.OrderFinishedAt = orderStatus.StatusTime
|
||
updateFields = append(updateFields, "OrderFinishedAt")
|
||
if order.LockStatus != model.OrderStatusUnknown {
|
||
order.LockStatus = model.OrderStatusUnknown
|
||
updateFields = append(updateFields, "LockStatus")
|
||
}
|
||
}
|
||
} else {
|
||
if model.IsOrderUnlockStatus(orderStatus.Status) {
|
||
order.LockStatus = model.OrderStatusUnknown
|
||
updateFields = append(updateFields, "LockStatus")
|
||
} else if model.IsOrderLockStatus(orderStatus.Status) {
|
||
if order.LockStatus != model.OrderStatusUnknown {
|
||
globals.SugarLogger.Warnf("addOrderStatus refOrderID:%s, orderID:%s, order.LockStatus:%d, status.LockStatus:%d", orderStatus.RefVendorOrderID, orderStatus.VendorOrderID, order.LockStatus, orderStatus.Status)
|
||
}
|
||
order.Flag &= ^model.OrderFlagMaskUserApplyCancel
|
||
order.LockStatus = orderStatus.Status
|
||
order.LockStatusTime = orderStatus.StatusTime
|
||
updateFields = append(updateFields, "LockStatus", "LockStatusTime", "Flag")
|
||
}
|
||
}
|
||
utils.CallFuncLogError(func() error {
|
||
_, err = db.Db.Update(order, updateFields...)
|
||
return err
|
||
}, "addOrderStatus update orderID:%s, status:%v", order.VendorOrderID, orderStatus)
|
||
} else {
|
||
isDuplicated = true
|
||
}
|
||
} else {
|
||
order = nil
|
||
if dao.IsNoRowsError(err) { // todo 消息错序
|
||
err = nil
|
||
} else {
|
||
globals.SugarLogger.Warnf("addOrderStatus orderID:%s read failed with error:%v", order.VendorOrderID, err)
|
||
}
|
||
}
|
||
}
|
||
return isDuplicated, order, err
|
||
}
|
||
|
||
func (c *OrderManager) loadOrderSku(db *dao.DaoDB, vendorOrderID string, vendorID int) (orderSkus []*model.OrderSku) {
|
||
utils.CallFuncLogError(func() (err error) {
|
||
_, err = db.Db.QueryTable("order_sku").Filter("vendor_order_id", vendorOrderID).Filter("vendor_id", vendorID).All(&orderSkus)
|
||
return err
|
||
}, "loadOrderSku orderID:%s", vendorOrderID)
|
||
return orderSkus
|
||
}
|
||
|
||
func (c *OrderManager) LoadStoreDetail(storeID, vendorID int) (storeDetail *dao.StoreDetail, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
)
|
||
storeDetail, err = dao.GetStoreDetail(db, storeID, vendorID, "")
|
||
return storeDetail, err
|
||
}
|
||
|
||
func (c *OrderManager) loadOrder(vendorOrderID, vendorOrderID2 string, vendorID int) (order *model.GoodsOrder, err error) {
|
||
db1 := dao.GetDB()
|
||
db := db1.Db
|
||
order = &model.GoodsOrder{
|
||
VendorOrderID: vendorOrderID,
|
||
VendorOrderID2: vendorOrderID2,
|
||
VendorID: vendorID,
|
||
}
|
||
keyFields := []string{
|
||
model.FieldVendorID,
|
||
}
|
||
if vendorOrderID != "" {
|
||
keyFields = append(keyFields, model.FieldVendorOrderID)
|
||
}
|
||
if vendorOrderID2 != "" {
|
||
keyFields = append(keyFields, model.FieldVendorOrderID2)
|
||
}
|
||
if err = db.Read(order, keyFields...); err == nil {
|
||
vendorOrderID = order.VendorOrderID
|
||
order.Skus = c.loadOrderSku(db1, vendorOrderID, vendorID)
|
||
}
|
||
if err != nil {
|
||
order = nil
|
||
if err == orm.ErrNoRows {
|
||
err = ErrCanNotFindOrder
|
||
}
|
||
globals.SugarLogger.Infof("LoadOrder orderID:%s failed with error:%v", vendorOrderID, err)
|
||
}
|
||
return order, err
|
||
}
|
||
|
||
func (c *OrderManager) LoadOrder(vendorOrderID string, vendorID int) (order *model.GoodsOrder, err error) {
|
||
return c.loadOrder(vendorOrderID, "", vendorID)
|
||
}
|
||
|
||
func (c *OrderManager) LoadOrder2(vendorOrderID2 string, vendorID int) (order *model.GoodsOrder, err error) {
|
||
return c.loadOrder("", vendorOrderID2, vendorID)
|
||
}
|
||
|
||
func (c *OrderManager) LoadOrderFinancial(vendorOrderID string, vendorID int) (order *model.OrderFinancial, err error) {
|
||
return c.loadOrderFinancial(vendorOrderID, "", vendorID)
|
||
}
|
||
|
||
func (c *OrderManager) LoadOrderFinancial2(vendorOrderID2 string, vendorID int) (order *model.OrderFinancial, err error) {
|
||
return c.loadOrderFinancial("", vendorOrderID2, vendorID)
|
||
}
|
||
|
||
func (c *OrderManager) loadOrderFinancial(vendorOrderID, vendorOrderID2 string, vendorID int) (order *model.OrderFinancial, err error) {
|
||
db := orm.NewOrm()
|
||
order = &model.OrderFinancial{
|
||
VendorOrderID: vendorOrderID,
|
||
VendorOrderID2: vendorOrderID2,
|
||
VendorID: vendorID,
|
||
}
|
||
keyFields := []string{
|
||
model.FieldVendorID,
|
||
}
|
||
if vendorOrderID != "" {
|
||
keyFields = append(keyFields, model.FieldVendorOrderID)
|
||
}
|
||
if vendorOrderID2 != "" {
|
||
keyFields = append(keyFields, model.FieldVendorOrderID2)
|
||
}
|
||
|
||
// 这块不知道怎么写了、、、标注一下
|
||
if err = db.Read(order, keyFields...); err == nil {
|
||
vendorOrderID = order.VendorOrderID
|
||
err = utils.CallFuncLogError(func() error {
|
||
_, err = db.QueryTable("order_sku_financial").Filter("vendor_order_id", vendorOrderID).Filter("vendor_id", vendorID).Filter("is_afs_order", 0).All(&order.Skus)
|
||
return err
|
||
}, "LoadOrder orderID:%s", vendorOrderID)
|
||
}
|
||
if err != nil {
|
||
order = nil
|
||
if err == orm.ErrNoRows {
|
||
err = ErrCanNotFindOrder
|
||
}
|
||
globals.SugarLogger.Infof("LoadOrderFinancial orderID:%s failed with error:%v", vendorOrderID, err)
|
||
}
|
||
return order, err
|
||
}
|
||
|
||
func (c *OrderManager) UpdateOrderStatusAndDeliveryFlag(order *model.GoodsOrder) (err error) {
|
||
return c.UpdateOrderFields(order, []string{"Status", "DeliveryFlag"})
|
||
}
|
||
|
||
func (c *OrderManager) UpdateOrderFields(order *model.GoodsOrder, fieldList []string) (err error) {
|
||
db := dao.GetDB()
|
||
utils.CallFuncLogError(func() error {
|
||
if order.ID == 0 {
|
||
order2 := *order
|
||
if err = dao.GetEntity(db, &order2, model.FieldVendorOrderID, model.FieldVendorID); err == nil {
|
||
order.ID = order2.ID
|
||
} else if dao.IsNoRowsError(err) {
|
||
err = nil // 强制忽略订单不存在错误
|
||
}
|
||
}
|
||
if err == nil && order.ID != 0 {
|
||
_, err = db.Db.Update(order, fieldList...)
|
||
}
|
||
return err
|
||
}, "UpdateOrderFields orderID:%s failed with error:%v", order.VendorOrderID, err)
|
||
return err
|
||
}
|
||
|
||
func (c *OrderManager) RefreshHistoryOrdersEarningPrice(ctx *jxcontext.Context, vendorOrderID string, actID int, vendorIDs []int, storeID int, fromDate, toDate string, isAsync, isContinueWhenError bool) (hint string, errCode string, err error) {
|
||
var (
|
||
orderList []*model.GoodsOrder
|
||
fromDateParam time.Time
|
||
toDateParam time.Time
|
||
beginAt time.Time
|
||
endAt time.Time
|
||
)
|
||
db := dao.GetDB()
|
||
if actID > 0 {
|
||
if fromDate != "" && toDate != "" {
|
||
fromDateParam = utils.Str2Time(fromDate)
|
||
toDateParam = utils.Str2Time(toDate)
|
||
actList, _ := dao.QueryActs(db, actID, 0, math.MaxInt32, 0, "", -1, nil, nil, nil, 0, nil, 0, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue)
|
||
if len(actList.Data) > 0 {
|
||
actBeginAt := actList.Data[0].BeginAt
|
||
actEndAt := actList.Data[0].EndAt
|
||
if fromDateParam.Sub(actBeginAt) > 0 && fromDateParam.Sub(actEndAt) > 0 {
|
||
return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("结算活动有效时间范围与订单创建时间范围不一致!,活动时间范围:[%v] 至 [%v] ,订单创建时间范围 :[%v] 至 [%v]", actBeginAt, actEndAt, fromDateParam, toDateParam))
|
||
}
|
||
if actBeginAt.Sub(toDateParam) > 0 && actEndAt.Sub(toDateParam) > 0 {
|
||
return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("结算活动有效时间范围与订单创建时间范围不一致!,活动时间范围:[%v] 至 [%v] ,订单创建时间范围 :[%v] 至 [%v]", actBeginAt, actEndAt, fromDateParam, toDateParam))
|
||
}
|
||
if fromDateParam.Sub(actBeginAt) > 0 {
|
||
beginAt = fromDateParam
|
||
if toDateParam.Sub(actEndAt) > 0 {
|
||
endAt = actEndAt
|
||
} else {
|
||
endAt = toDateParam
|
||
}
|
||
} else {
|
||
beginAt = actBeginAt
|
||
if toDateParam.Sub(actEndAt) > 0 {
|
||
endAt = actEndAt
|
||
} else {
|
||
endAt = toDateParam
|
||
}
|
||
}
|
||
orderList, _ = dao.QueryOrders(db, vendorOrderID, actID, vendorIDs, storeID, beginAt, endAt)
|
||
} else {
|
||
return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("未查询到相关结算活动,活动ID:[%d]", actID))
|
||
}
|
||
} else if fromDate == "" && toDate == "" {
|
||
actList, _ := dao.QueryActs(db, actID, 0, math.MaxInt32, 0, "", -1, nil, nil, nil, 0, nil, 0, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue)
|
||
if len(actList.Data) > 0 {
|
||
orderList, _ = dao.QueryOrders(db, vendorOrderID, actID, vendorIDs, storeID, actList.Data[0].BeginAt, actList.Data[0].EndAt)
|
||
if len(orderList) == 0 {
|
||
return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("未查询到相关订单!开始时间:[%v],结束时间:[%v]", actList.Data[0].BeginAt, actList.Data[0].EndAt))
|
||
}
|
||
} else {
|
||
return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("未查询到相关结算活动,活动ID:[%d]", actID))
|
||
}
|
||
} else {
|
||
return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("间隔时间必须完整!时间范围:[%v] 至 [%v]", fromDate, toDate))
|
||
}
|
||
} else {
|
||
if fromDate != "" && toDate != "" {
|
||
fromDateParam = utils.Str2Time(fromDate)
|
||
toDateParam = utils.Str2Time(toDate)
|
||
//若未传入活动ID,且时间间隔大于10天则不允许查询
|
||
if math.Ceil(toDateParam.Sub(fromDateParam).Hours()/24) > 10 {
|
||
return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("查询间隔时间不允许大于10天!时间范围:[%v] 至 [%v]", fromDate, toDate))
|
||
}
|
||
orderList, _ = dao.QueryOrders(db, vendorOrderID, actID, vendorIDs, storeID, fromDateParam, toDateParam)
|
||
} else {
|
||
return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("若不按活动查询则间隔时间必须完整!时间范围:[%v] 至 [%v]", fromDate, toDate))
|
||
}
|
||
}
|
||
if len(orderList) <= 0 {
|
||
return "", model.ErrCodePoint, errors.New(fmt.Sprintf("所选活动没有要更新结算价的订单!,vendorOrderID : %s, actID : %d, 时间范围:[%v] 至 [%v]", vendorOrderID, actID, fromDate, toDate))
|
||
}
|
||
task := tasksch.NewParallelTask("刷新历史订单结算价", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
|
||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
order := batchItemList[0].(*model.GoodsOrder)
|
||
db := dao.GetDB()
|
||
updateSingleOrderEarningPrice(order, db)
|
||
txDB, _ := dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil || err != nil {
|
||
dao.Rollback(db, txDB)
|
||
if r != nil {
|
||
panic(r)
|
||
}
|
||
}
|
||
}()
|
||
for _, value := range order.Skus {
|
||
// storeID := 0
|
||
// if order.StoreID == 0 {
|
||
// storeID = order.JxStoreID
|
||
// } else {
|
||
// storeID = order.StoreID
|
||
// }
|
||
// result, _ := dao.GetEffectiveActStoreSkuInfo(db, 0, nil, 0, []int{storeID}, []int{value.SkuID}, order.OrderCreatedAt, order.OrderCreatedAt)
|
||
// if len(result) > 0 {
|
||
// if result[0].EarningPrice != 0 {
|
||
// var (
|
||
// storePayPercentage int
|
||
// )
|
||
// stores, _ := dao.GetStoreList(db, []int{order.StoreID}, nil, nil, nil, "")
|
||
// if len(stores) > 0 {
|
||
// storePayPercentage = stores[0].PayPercentage
|
||
// } else {
|
||
// storePayPercentage = 70
|
||
// }
|
||
// sku := value
|
||
// sku.Count = value.Count - 1
|
||
// value.Count = 1
|
||
// if value.ShopPrice < value.SalePrice {
|
||
// sku.EarningPrice = value.ShopPrice * int64(storePayPercentage)
|
||
// } else {
|
||
// sku.EarningPrice = value.SalePrice * int64(storePayPercentage)
|
||
// }
|
||
// order.Skus = append(order.Skus, sku)
|
||
// }
|
||
// }
|
||
if _, err = dao.UpdateEntity(db, value, "EarningPrice", "StoreSubID"); err != nil {
|
||
return nil, err
|
||
}
|
||
}
|
||
jxutils.RefreshOrderSkuRelated(order)
|
||
storeID := 0
|
||
if order.StoreID == 0 {
|
||
storeID = order.JxStoreID
|
||
} else {
|
||
storeID = order.StoreID
|
||
}
|
||
store, _ := dao.GetStoreDetail(db, storeID, order.VendorID, "")
|
||
payPercentage := store.PayPercentage
|
||
if payPercentage <= 50 {
|
||
order.NewEarningPrice = order.TotalShopMoney * int64((100 - payPercentage/2)) / 100
|
||
} else {
|
||
order.NewEarningPrice = order.EarningPrice
|
||
}
|
||
num, err := dao.UpdateEntity(db, order, "EarningPrice", "NewEarningPrice")
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
dao.Commit(db, txDB)
|
||
retVal = []string{utils.Int64ToStr(num)}
|
||
return retVal, err
|
||
}, orderList)
|
||
tasksch.HandleTask(task, nil, true).Run()
|
||
if !isAsync {
|
||
resultNum, err2 := task.GetResult(0)
|
||
if err = err2; err == nil {
|
||
hint = resultNum[0].(string)
|
||
}
|
||
} else {
|
||
hint = task.GetID()
|
||
}
|
||
return hint, model.ErrCodeSuccess, err
|
||
}
|
||
|
||
func RefreshOrdersWithoutJxStoreID(ctx *jxcontext.Context, fromDate, toDate string, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||
var (
|
||
fromDateParam time.Time
|
||
toDateParam time.Time
|
||
)
|
||
if fromDate != "" {
|
||
fromDateParam = utils.Str2Time(fromDate)
|
||
}
|
||
if toDate != "" {
|
||
toDateParam = utils.Str2Time(toDate)
|
||
}
|
||
db := dao.GetDB()
|
||
task := tasksch.NewParallelTask("订单门店归属补漏", tasksch.NewParallelConfig().SetParallelCount(1), ctx,
|
||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
_, err = dao.UpdateOrdersWithoutJxStoreID(db, fromDateParam, toDateParam)
|
||
return retVal, err
|
||
}, []int{0})
|
||
tasksch.HandleTask(task, nil, true).Run()
|
||
if !isAsync {
|
||
_, err = task.GetResult(0)
|
||
hint = "1"
|
||
} else {
|
||
hint = task.GetID()
|
||
}
|
||
return hint, err
|
||
}
|
||
|
||
func GetOrdersSupplement(ctx *jxcontext.Context, storIDs, vendorIDs, statuss []int, vendorOrderID, fromTime, toTime string, stype, IsReverse, offset, pageSize int) (pageInfo *model.PagedInfo, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
fromTimeP time.Time
|
||
toTimeP time.Time
|
||
)
|
||
if fromTime != "" {
|
||
fromTimeP = utils.Str2Time(fromTime)
|
||
}
|
||
if toTime != "" {
|
||
toTimeP = utils.Str2Time(toTime)
|
||
}
|
||
if fromTimeP.After(toTimeP) {
|
||
return nil, fmt.Errorf("时间范围不合法!开始时间:[%v],结束时间:[%v]", fromTimeP, toTimeP)
|
||
}
|
||
result, totalCount, err := dao.GetOrdersSupplement(db, storIDs, vendorIDs, statuss, vendorOrderID, fromTimeP, toTimeP, stype, IsReverse, offset, pageSize)
|
||
pageInfo = &model.PagedInfo{
|
||
Data: result,
|
||
TotalCount: totalCount,
|
||
}
|
||
return pageInfo, err
|
||
}
|
||
|
||
func AddUpdateOrdersSupplement(ctx *jxcontext.Context, ordersSupplement *model.OrderSupplementFee) (num int64, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
id = ordersSupplement.ID
|
||
)
|
||
now := time.Now()
|
||
ordersSupplement.SupplementTime = &now
|
||
txDB, _ := dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil || err != nil {
|
||
dao.Rollback(db, txDB)
|
||
if r != nil {
|
||
panic(r)
|
||
}
|
||
}
|
||
}()
|
||
if id > 0 {
|
||
orderSupplementFee, _ := dao.GetOrdersSupplementNoPage(db, id, nil, nil, nil, "", utils.ZeroTimeValue, utils.ZeroTimeValue, 0, 0)
|
||
if len(orderSupplementFee) > 2 || len(orderSupplementFee) == 0 {
|
||
return 0, fmt.Errorf("查询扣款记录有误,请联系技术部!")
|
||
}
|
||
if orderSupplementFee[0].Status == 1 {
|
||
return 0, fmt.Errorf("已结账的扣款信息不允许修改!门店ID:[%v],订单号:[%v]", ordersSupplement.StoreID, ordersSupplement.VendorOrderID)
|
||
}
|
||
ordersSupplement.UpdatedAt = time.Now()
|
||
ordersSupplement.LastOperator = ctx.GetUserName()
|
||
ordersSupplement.CreatedAt = orderSupplementFee[0].CreatedAt
|
||
if ordersSupplement.Status == -1 {
|
||
ordersSupplement.DeletedAt = time.Now()
|
||
} else {
|
||
ordersSupplement.DeletedAt = utils.DefaultTimeValue
|
||
}
|
||
num, err = dao.UpdateEntity(db, ordersSupplement)
|
||
} else {
|
||
dao.WrapAddIDCULDEntity(ordersSupplement, ctx.GetUserName())
|
||
err = dao.CreateEntity(db, ordersSupplement)
|
||
}
|
||
dao.Commit(db, txDB)
|
||
return num, err
|
||
}
|
||
|
||
func RefreshOrdersPriceInfo(ctx *jxcontext.Context, fromTime, toTime time.Time, isAsync, isContinueWhenError bool) (hint string, err error) {
|
||
if utils.IsTimeZero(fromTime) {
|
||
return "", fmt.Errorf("必须指定起始时间")
|
||
}
|
||
if utils.IsTimeZero(toTime) {
|
||
toTime = fromTime
|
||
}
|
||
|
||
db := dao.GetDB()
|
||
orderList, err := dao.QueryOrders(db, "", 0, nil, 0, fromTime, toTime)
|
||
if err == nil && len(orderList) > 0 {
|
||
task := tasksch.NewParallelTask("RefreshOrdersPriceInfo", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx,
|
||
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
|
||
curOrder := batchItemList[0].(*model.GoodsOrder)
|
||
newOrder, err := FixedOrderManager.LoadOrder(curOrder.VendorOrderID, curOrder.VendorID)
|
||
if err == nil {
|
||
db := dao.GetDB()
|
||
if err = FixedOrderManager.updateOrderOtherInfo(newOrder, db); err == nil {
|
||
txDB, _ := dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db, txDB)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if _, err = dao.UpdateEntity(db, newOrder); err != nil {
|
||
dao.Rollback(db, txDB)
|
||
return nil, err
|
||
}
|
||
|
||
for _, sku := range newOrder.Skus {
|
||
if _, err = dao.UpdateEntity(db, sku); err != nil {
|
||
dao.Rollback(db, txDB)
|
||
return nil, err
|
||
}
|
||
}
|
||
dao.Commit(db, txDB)
|
||
}
|
||
}
|
||
return retVal, err
|
||
}, orderList)
|
||
tasksch.HandleTask(task, nil, true).Run()
|
||
if isAsync {
|
||
hint = task.GetID()
|
||
} else {
|
||
_, err = task.GetResult(0)
|
||
hint = "1"
|
||
}
|
||
}
|
||
return hint, err
|
||
}
|
||
|
||
type GetOrderSimpleInfoResult struct {
|
||
VendorOrderID string `orm:"column(vendor_order_id)" json:"vendorOrderID"`
|
||
Status int `json:"status"`
|
||
WaybillVendorID int `orm:"column(waybill_vendor_id)" json:"waybillVendorID"`
|
||
CourierName string `json:"courierName"`
|
||
CourierMobile string `json:"courierMobile"`
|
||
Tel1 string `json:"tel1"`
|
||
MarketManPhone string `json:"marketManPhone"`
|
||
}
|
||
|
||
func GetOrderSimpleInfo(ctx *jxcontext.Context, vendorOrderID string) (getOrderSimpleInfoResult *GetOrderSimpleInfoResult, err error) {
|
||
db := dao.GetDB()
|
||
sql := `
|
||
SELECT a.vendor_order_id, a.status, a.waybill_vendor_id, c.courier_name, c.courier_mobile, b.tel1, b.market_man_phone
|
||
FROM goods_order a
|
||
JOIN store b ON IF(a.store_id <> '', a.store_id, a.jx_store_id) = b.id
|
||
LEFT JOIN waybill c ON c.vendor_order_id = a.vendor_order_id
|
||
WHERE (a.vendor_order_id LIKE ? OR a.consignee_mobile LIKE ?)
|
||
ORDER BY a.order_created_at DESC
|
||
LIMIT 1
|
||
`
|
||
sqlParams := []interface{}{
|
||
"%" + vendorOrderID + "%",
|
||
"%" + vendorOrderID + "%",
|
||
}
|
||
err = dao.GetRow(db, &getOrderSimpleInfoResult, sql, sqlParams)
|
||
if getOrderSimpleInfoResult == nil {
|
||
return getOrderSimpleInfoResult, fmt.Errorf("未查询到该订单的信息!")
|
||
}
|
||
|
||
return getOrderSimpleInfoResult, err
|
||
}
|
||
|
||
func setJdsOrderSeq(order *model.GoodsOrder) (err error) {
|
||
type tCount struct {
|
||
Count int `json:"count"`
|
||
}
|
||
var counts []*tCount
|
||
sql := `
|
||
SELECT count(*) count FROM goods_order WHERE store_id = ? AND order_created_at >= ? AND order_created_at <= ? AND vendor_id = ?
|
||
`
|
||
sqlParams := []interface{}{
|
||
order.StoreID, utils.Time2Date(time.Now()), utils.Time2Date(time.Now().AddDate(0, 0, 1)), order.VendorID,
|
||
}
|
||
err = dao.GetRows(dao.GetDB(), &counts, sql, sqlParams)
|
||
order.OrderSeq = counts[0].Count + 1
|
||
return err
|
||
}
|
||
|
||
func MergeJdsOrders(ctx *jxcontext.Context, vendorOrderIDs []string) (vendorOrderIDJds string, err error) {
|
||
globals.SugarLogger.Debugf("jds MergeJdsOrders vendorOrderIDs: %v", vendorOrderIDs)
|
||
var (
|
||
db = dao.GetDB()
|
||
orders []*model.GoodsOrder
|
||
orderSkus []*model.OrderSku
|
||
orderIDs []string
|
||
storeDuplicate = make(map[int]int)
|
||
storeID int
|
||
)
|
||
for _, vendorOrderID := range vendorOrderIDs {
|
||
order, _ := dao.GetSimpleOrder(db, vendorOrderID)
|
||
if err != nil || order == nil {
|
||
return "", fmt.Errorf("未查询到该订单!订单号:[%v]", vendorOrderID)
|
||
}
|
||
if order.Status >= model.OrderStatusDelivering && order.Status != model.OrderStatusCanceled {
|
||
return "", fmt.Errorf("暂不支持此状态的订单进行转移!订单号:[%v]", vendorOrderID)
|
||
}
|
||
if order.VendorID != model.VendorIDJDShop {
|
||
return "", fmt.Errorf("暂不支持非京狗的订单进行转移!订单号:[%v]", vendorOrderID)
|
||
}
|
||
storeDuplicate[jxutils.GetSaleStoreIDFromOrder(order)] = jxutils.GetSaleStoreIDFromOrder(order)
|
||
orders = append(orders, order)
|
||
|
||
//订单商品
|
||
skus, _ := dao.GetSimpleOrderSkus(db, order.VendorOrderID, nil)
|
||
orderSkus = append(orderSkus, skus...)
|
||
|
||
orderIDs = append(orderIDs, vendorOrderID)
|
||
}
|
||
if len(storeDuplicate) > 1 {
|
||
return "", fmt.Errorf("只能选择相同门店的订单进行合并!")
|
||
} else {
|
||
storeID = jxutils.GetSaleStoreIDFromOrder(orders[0])
|
||
}
|
||
for _, order := range orders {
|
||
var waybill *model.Waybill
|
||
//将订单和运单取消
|
||
waybills, err := dao.GetWaybills(db, order.VendorOrderID)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
if len(waybills) > 0 {
|
||
for _, v := range waybills {
|
||
if v.Status != model.WaybillStatusCanceled {
|
||
waybill = v
|
||
}
|
||
}
|
||
if waybill != nil {
|
||
if waybill.WaybillVendorID != model.VendorIDJDWL {
|
||
if handler := partner.GetDeliveryPlatformFromVendorID(waybill.WaybillVendorID); handler != nil {
|
||
err = handler.Handler.CancelWaybill(waybill, 0, "订单合并被取消")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if err = jdshop.ChangeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, "订单合并被取消"); err != nil {
|
||
return "", err
|
||
}
|
||
}
|
||
//重新构建order的数据
|
||
storeMaps, err := dao.GetStoresMapList(db, []int{model.VendorIDJDShop}, []int{storeID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "", "")
|
||
if err != nil || len(storeMaps) == 0 {
|
||
return "", fmt.Errorf("该门店未绑定京狗平台,请先绑定后再转移!门店:[%v]", storeID)
|
||
}
|
||
stores, _ := dao.GetStoreList(db, []int{storeID}, nil, nil, nil, nil, "")
|
||
var (
|
||
newEarningPrice int64
|
||
actualPrice int64
|
||
shopPrice int64
|
||
salePrice int64
|
||
totalShop int64
|
||
)
|
||
for _, v := range orders {
|
||
newEarningPrice += v.NewEarningPrice
|
||
actualPrice += v.ActualPayPrice
|
||
shopPrice += v.ShopPrice
|
||
salePrice += v.SalePrice
|
||
totalShop += v.TotalShopMoney
|
||
}
|
||
store := stores[0]
|
||
order := orders[0]
|
||
order.ID = 0
|
||
order.NewEarningPrice = newEarningPrice
|
||
order.ActualPayPrice = actualPrice
|
||
order.SalePrice = salePrice
|
||
order.ShopPrice = shopPrice
|
||
order.TotalShopMoney = totalShop
|
||
order.VendorOrderID = utils.Int64ToStr(utils.Str2Int64(orders[0].VendorOrderID2)*1000000) + utils.Int2Str(time.Now().Second())
|
||
if len(order.VendorOrderID) < 18 {
|
||
order.VendorOrderID = order.VendorOrderID + "0"
|
||
}
|
||
order.VendorOrderID2 = strings.Join(orderIDs, ",")
|
||
order.Status = model.OrderStatusNew
|
||
setJdsOrderSeq(order)
|
||
if order.BusinessType == model.BusinessTypeImmediate {
|
||
var (
|
||
opentime1 = jxutils.JxOperationTime2TimeByDate(store.OpenTime1, order.CreatedAt)
|
||
opentime2 = jxutils.JxOperationTime2TimeByDate(store.OpenTime2, order.CreatedAt)
|
||
closetime1 = jxutils.JxOperationTime2TimeByDate(store.CloseTime1, order.CreatedAt)
|
||
closetime2 = jxutils.JxOperationTime2TimeByDate(store.CloseTime2, order.CreatedAt)
|
||
orderCreatedAt = order.CreatedAt
|
||
)
|
||
if store.OpenTime1 == 0 || store.CloseTime1 == 0 {
|
||
return "", fmt.Errorf("该门店没有营业时间,不能接单!门店:[%v]", storeID)
|
||
}
|
||
if !(orderCreatedAt.Sub(opentime1) >= 0 && orderCreatedAt.Sub(closetime1) <= 0) {
|
||
if store.OpenTime2 != 0 && store.CloseTime2 != 0 {
|
||
if !(orderCreatedAt.Sub(opentime2) >= 0 && orderCreatedAt.Sub(closetime2) <= 0) {
|
||
if orderCreatedAt.Sub(opentime1) < 0 {
|
||
order.ExpectedDeliveredTime = opentime1
|
||
order.BusinessType = model.BusinessTypeDingshida
|
||
} else {
|
||
if orderCreatedAt.Sub(opentime2) < 0 {
|
||
order.ExpectedDeliveredTime = opentime2
|
||
} else {
|
||
order.ExpectedDeliveredTime = opentime1.AddDate(0, 0, 1)
|
||
}
|
||
order.BusinessType = model.BusinessTypeDingshida
|
||
}
|
||
}
|
||
} else {
|
||
if orderCreatedAt.Sub(opentime1) < 0 {
|
||
order.ExpectedDeliveredTime = opentime1
|
||
} else {
|
||
order.ExpectedDeliveredTime = opentime1.AddDate(0, 0, 1)
|
||
}
|
||
order.BusinessType = model.BusinessTypeDingshida
|
||
}
|
||
}
|
||
}
|
||
//结算类型
|
||
if store.PayPercentage < 50 {
|
||
order.EarningType = model.EarningTypePoints
|
||
} else {
|
||
order.EarningType = model.EarningTypeQuote
|
||
}
|
||
if storeID != model.JdShopMainStoreID {
|
||
order.DeliveryFlag = model.NO
|
||
}
|
||
//skus
|
||
for _, sku := range orderSkus {
|
||
sku.VendorOrderID = order.VendorOrderID
|
||
sku.ID = 0
|
||
}
|
||
order.Skus = orderSkus
|
||
err = partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order))
|
||
vendorOrderIDJds = order.VendorOrderID
|
||
return vendorOrderIDJds, err
|
||
}
|
||
|
||
func TransferJdsOrder(ctx *jxcontext.Context, vendorOrderID string, storeID int) (vendorOrderIDJds string, err error) {
|
||
globals.SugarLogger.Debugf("jds TransferJdsOrder vendorOrderID: %v, storeID : %v", vendorOrderID, storeID)
|
||
var (
|
||
db = dao.GetDB()
|
||
waybill *model.Waybill
|
||
)
|
||
order, err := dao.GetSimpleOrder(db, vendorOrderID)
|
||
if err != nil || order == nil {
|
||
return "", fmt.Errorf("未查询到该订单!订单号:[%v]", vendorOrderID)
|
||
}
|
||
if order.Status >= model.OrderStatusDelivering && order.Status != model.OrderStatusCanceled {
|
||
return "", fmt.Errorf("暂不支持此状态的订单进行转移!")
|
||
}
|
||
if order.VendorID != model.VendorIDJDShop && order.VendorID != model.VendorIDJX {
|
||
return "", fmt.Errorf("暂不支持该平台的订单进行转移!")
|
||
}
|
||
skus, err := dao.GetSimpleOrderSkus(db, vendorOrderID, nil)
|
||
if err != nil || order == nil {
|
||
return "", fmt.Errorf("未查询到该订单商品!订单号:[%v]", vendorOrderID)
|
||
}
|
||
//将订单和运单取消
|
||
waybills, err := dao.GetWaybills(db, vendorOrderID)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
if len(waybills) > 0 {
|
||
for _, v := range waybills {
|
||
if v.Status != model.WaybillStatusCanceled {
|
||
waybill = v
|
||
}
|
||
}
|
||
if waybill != nil {
|
||
if handler := partner.GetDeliveryPlatformFromVendorID(waybill.WaybillVendorID); handler != nil {
|
||
err = handler.Handler.CancelWaybill(waybill, 0, "订单转移被取消")
|
||
}
|
||
}
|
||
}
|
||
//重新构建order的数据
|
||
storeMaps, err := dao.GetStoresMapList(db, []int{order.VendorID}, []int{storeID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "", order.VendorOrgCode)
|
||
if err != nil || len(storeMaps) == 0 {
|
||
return "", fmt.Errorf("该门店未绑定平台,请先绑定后再转移!门店:[%v]", storeID)
|
||
}
|
||
stores, err := dao.GetStoreList(db, []int{storeID}, nil, nil, nil, nil, "")
|
||
if len(storeMaps) > 0 && len(stores) > 0 {
|
||
if storeMaps[0].VendorStoreID == "" {
|
||
return "", fmt.Errorf("该门店未绑定平台,或绑定有误,请联系技术部!门店:[%v]", storeID)
|
||
}
|
||
order.StoreID = storeID
|
||
order.StoreName = stores[0].Name
|
||
order.VendorStoreID = storeMaps[0].VendorStoreID
|
||
//如果是立即达的订单,要判断一下下单时间是否在门店营业时间范围内
|
||
//若没有,则要把这个订单变成定时达,预计送达时间改为门店的营业时间
|
||
//如果门店没有营业时间,则直接报错
|
||
if order.BusinessType == model.BusinessTypeImmediate {
|
||
store := stores[0]
|
||
var (
|
||
opentime1 = jxutils.JxOperationTime2TimeByDate(store.OpenTime1, order.OrderCreatedAt)
|
||
opentime2 = jxutils.JxOperationTime2TimeByDate(store.OpenTime2, order.OrderCreatedAt)
|
||
closetime1 = jxutils.JxOperationTime2TimeByDate(store.CloseTime1, order.OrderCreatedAt)
|
||
closetime2 = jxutils.JxOperationTime2TimeByDate(store.CloseTime2, order.OrderCreatedAt)
|
||
orderCreatedAt = order.OrderCreatedAt
|
||
)
|
||
if store.OpenTime1 == 0 || store.CloseTime1 == 0 {
|
||
return "", fmt.Errorf("该门店没有营业时间,不能接单!门店:[%v]", storeID)
|
||
}
|
||
if closetime1.Sub(opentime1) <= time.Hour {
|
||
return "", fmt.Errorf("该门店营业时间间隔过小,请确认!门店:[%v]", storeID)
|
||
}
|
||
if !(orderCreatedAt.Sub(opentime1) >= 0 && orderCreatedAt.Sub(closetime1) <= 0) {
|
||
if store.OpenTime2 != 0 && store.CloseTime2 != 0 {
|
||
if !(orderCreatedAt.Sub(opentime2) >= 0 && orderCreatedAt.Sub(closetime2) <= 0) {
|
||
if orderCreatedAt.Sub(opentime1) < 0 {
|
||
order.ExpectedDeliveredTime = opentime1
|
||
order.BusinessType = model.BusinessTypeDingshida
|
||
} else {
|
||
if orderCreatedAt.Sub(opentime2) < 0 {
|
||
order.ExpectedDeliveredTime = opentime2
|
||
} else {
|
||
order.ExpectedDeliveredTime = opentime1.AddDate(0, 0, 1)
|
||
}
|
||
order.BusinessType = model.BusinessTypeDingshida
|
||
}
|
||
}
|
||
} else {
|
||
if orderCreatedAt.Sub(opentime1) < 0 {
|
||
order.ExpectedDeliveredTime = opentime1
|
||
} else {
|
||
order.ExpectedDeliveredTime = opentime1.AddDate(0, 0, 1)
|
||
}
|
||
order.BusinessType = model.BusinessTypeDingshida
|
||
}
|
||
}
|
||
}
|
||
//结算类型
|
||
if stores[0].PayPercentage < 50 {
|
||
order.EarningType = model.EarningTypePoints
|
||
} else {
|
||
order.EarningType = model.EarningTypeQuote
|
||
}
|
||
} else {
|
||
return "", fmt.Errorf("未查询到该门店对应的平台信息!门店:[%v]", order.StoreID)
|
||
}
|
||
if order.VendorID == model.VendorIDJDShop {
|
||
if len(order.VendorOrderID) > 12 {
|
||
var goodsOrders []*model.GoodsOrder
|
||
sql := `
|
||
SELECT * FROM goods_order WHERE vendor_order_id2 = ? ORDER BY vendor_order_id DESC
|
||
`
|
||
sqlParams := []interface{}{order.VendorOrderID2}
|
||
err = dao.GetRows(db, &goodsOrders, sql, sqlParams)
|
||
for _, order := range goodsOrders {
|
||
if order.Status != model.OrderStatusCanceled {
|
||
err = jdshop.ChangeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, "订单转移被取消")
|
||
}
|
||
}
|
||
// suffix := utils.Str2Int(goodsOrders[0].VendorOrderID[12:len(goodsOrders[0].VendorOrderID)])
|
||
// suffix++
|
||
if len(order.VendorOrderID2) > 18 {
|
||
order.VendorOrderID2 = order.VendorOrderID2[0:12]
|
||
}
|
||
order.VendorOrderID = utils.Int64ToStr(utils.Str2Int64(order.VendorOrderID2)*1000000) + utils.Int2Str(time.Now().Second())
|
||
if len(order.VendorOrderID) < 18 {
|
||
order.VendorOrderID = order.VendorOrderID + "0"
|
||
}
|
||
}
|
||
if storeID != model.JdShopMainStoreID {
|
||
order.DeliveryFlag = model.NO
|
||
}
|
||
err = jdshop.ChangeOrderStatus(vendorOrderID, model.OrderStatusCanceled, "订单转移被取消")
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
order.Status = model.OrderStatusNew
|
||
if order.ActualPayPrice == 0 {
|
||
msg, err := jdshop.GetJdsOrder(order.VendorOrderID2, order.VendorOrgCode)
|
||
if err == nil {
|
||
if jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)) == 0 {
|
||
order.ActualPayPrice = jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderTotalPrice) + utils.Str2Float64(msg.FreightPrice) - utils.Str2Float64(msg.SellerDiscount))
|
||
} else {
|
||
order.ActualPayPrice = jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment))
|
||
}
|
||
order.TotalShopMoney = utils.Float64TwoInt64(float64(order.ActualPayPrice) * jdshopapi.JdsPayPercentage)
|
||
}
|
||
}
|
||
} else {
|
||
order.VendorOrderID2 = order.VendorOrderID
|
||
order.VendorOrderID = utils.Int64ToStr(jxutils.GenOrderNo())
|
||
order.DeliveryFlag = model.NO
|
||
orderStatus := &model.OrderStatus{
|
||
VendorOrderID: vendorOrderID,
|
||
VendorID: model.VendorIDJX,
|
||
OrderType: model.OrderTypeOrder,
|
||
RefVendorOrderID: vendorOrderID,
|
||
RefVendorID: model.VendorIDJX,
|
||
VendorStatus: utils.Int2Str(model.OrderStatusCanceled),
|
||
Status: model.OrderStatusCanceled,
|
||
StatusTime: time.Now(),
|
||
Remark: "订单转移被取消",
|
||
}
|
||
jxutils.CallMsgHandlerAsync(func() {
|
||
err = partner.CurOrderManager.OnOrderStatusChanged(order.VendorOrgCode, orderStatus)
|
||
}, jxutils.ComposeUniversalOrderID(vendorOrderID, model.VendorIDJX))
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
if order.VendorOrgCode == "1" {
|
||
order.Status = model.OrderStatusAccepted
|
||
} else {
|
||
order.Status = model.OrderStatusNew
|
||
}
|
||
}
|
||
for _, sku := range skus {
|
||
sku.VendorOrderID = order.VendorOrderID
|
||
sku.ID = 0
|
||
var storesSku *model.StoreSkuBind
|
||
sql := `
|
||
SELECT * FROM store_sku_bind WHERE deleted_at = ? AND store_id = ? AND jds_id = ?
|
||
`
|
||
sqlParams := []interface{}{utils.DefaultTimeValue, model.JdShopMainStoreID, sku.VendorSkuID}
|
||
if err = dao.GetRow(db, &storesSku, sql, sqlParams); err == nil && storesSku != nil {
|
||
if realStoresSkus, err := dao.GetStoresSkusInfo(db, []int{storeID}, []int{storesSku.SkuID}); err == nil && len(realStoresSkus) > 0 {
|
||
sku.ShopPrice = int64(realStoresSkus[0].Price)
|
||
}
|
||
}
|
||
order.Skus = append(order.Skus, sku)
|
||
}
|
||
setJdsOrderSeq(order)
|
||
err = partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order))
|
||
vendorOrderIDJds = order.VendorOrderID
|
||
return vendorOrderIDJds, err
|
||
}
|
||
|
||
func SendJdwlForJdsOrder(ctx *jxcontext.Context, vendorOrderID string) (err error) {
|
||
db := dao.GetDB()
|
||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJDShop)
|
||
if order == nil || err != nil {
|
||
return fmt.Errorf("目前只支持京狗订单创建!")
|
||
}
|
||
if order.Status >= model.OrderStatusDelivering {
|
||
return fmt.Errorf("订单当前状态不支持创建!")
|
||
}
|
||
waybill := &model.Waybill{}
|
||
waybills, err := dao.GetWaybills(db, vendorOrderID)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if len(waybills) > 0 {
|
||
for _, v := range waybills {
|
||
if v.Status != model.WaybillStatusCanceled {
|
||
waybill = v
|
||
}
|
||
}
|
||
if handler := partner.GetDeliveryPlatformFromVendorID(model.VendorIDJDWL); handler != nil {
|
||
err = handler.Handler.CancelWaybill(waybill, 0, "订单已发送其他物流")
|
||
}
|
||
if err != nil {
|
||
return err
|
||
}
|
||
}
|
||
var vendorWaybillID string
|
||
if order.StoreID == model.JdShopMainStoreID {
|
||
var (
|
||
goodsNos []string
|
||
prices []string
|
||
quantities []string
|
||
)
|
||
for _, v := range order.Skus {
|
||
skus, err := dao.GetSkus(db, []int{v.SkuID}, nil, nil, nil, nil)
|
||
if err != nil || len(skus) == 0 {
|
||
continue
|
||
}
|
||
goodsNos = append(goodsNos, skus[0].EclpID)
|
||
prices = append(prices, "0")
|
||
quantities = append(quantities, utils.Int2Str(v.Count))
|
||
}
|
||
eclpSoNo, err := api.JdEclpAPI.AddOrder(&jdeclpapi.AddOrderParam{
|
||
IsvUUID: order.VendorOrderID,
|
||
IsvSource: jdeclpapi.IsvSource,
|
||
ShopNo: jdeclpapi.ShopNo,
|
||
DepartmentNo: jdeclpapi.DepartmentNo,
|
||
WarehouseNo: jdeclpapi.WarehouseNo,
|
||
ShipperNo: jdeclpapi.ShipperNo,
|
||
SalesPlatformOrderNo: order.VendorOrderID,
|
||
SalePlatformSource: jdeclpapi.SalePlatformSource,
|
||
ConsigneeName: order.ConsigneeName,
|
||
ConsigneeMobile: order.ConsigneeMobile,
|
||
ConsigneeAddress: order.ConsigneeAddress,
|
||
OrderMark: jdeclpapi.OrderMark,
|
||
GoodsNo: strings.Join(goodsNos, ","),
|
||
Price: strings.Join(prices, ","),
|
||
Quantity: strings.Join(quantities, ","),
|
||
})
|
||
waybill := &model.Waybill{
|
||
VendorOrderID: order.VendorOrderID,
|
||
OrderVendorID: model.VendorIDJX,
|
||
VendorWaybillID: eclpSoNo,
|
||
WaybillVendorID: model.VendorIDJDWL,
|
||
Status: model.WaybillStatusDelivering,
|
||
WaybillCreatedAt: time.Now(),
|
||
StatusTime: time.Now(),
|
||
WaybillFinishedAt: utils.DefaultTimeValue,
|
||
DeliveryFlag: model.OrderDeliveryFlagMaskScheduleDisabled,
|
||
}
|
||
dao.CreateEntity(db, waybill)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
order.EclpOutID = eclpSoNo
|
||
dao.UpdateEntity(db, order, "EclpOutID")
|
||
vendorWaybillID = eclpSoNo
|
||
} else {
|
||
// if handler := partner.GetDeliveryPlatformFromVendorID(model.VendorIDJDWL); handler != nil {
|
||
// waybill2, err := handler.Handler.CreateWaybill(order, 0)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
// vendorWaybillID = waybill2.VendorWaybillID
|
||
// }
|
||
}
|
||
jdshop.CurPurchaseHandler.OrderExport(ctx, vendorOrderID, vendorWaybillID, false)
|
||
return err
|
||
}
|
||
|
||
func AdjustJdsOrderSimple(ctx *jxcontext.Context, vendorOrderID string, skuID int) (err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
)
|
||
orderSkus, err := dao.GetSimpleOrderSkus(db, vendorOrderID, []int{skuID})
|
||
order, err := dao.GetSimpleOrder(db, vendorOrderID)
|
||
//如果不是商城模板店
|
||
if jxutils.GetSaleStoreIDFromOrder(order) != model.JdShopMainStoreID {
|
||
return fmt.Errorf("目前只支持商城模板店的简单售前删除!")
|
||
}
|
||
orderSkus2, err := dao.GetSimpleOrderSkus(db, vendorOrderID, nil)
|
||
if len(orderSkus2) == 1 {
|
||
return fmt.Errorf("这一单只剩这最后一个商品了,不允许删除!")
|
||
}
|
||
if len(orderSkus) == 0 {
|
||
return fmt.Errorf("未查询到该订单商品!")
|
||
}
|
||
if order.Status > model.OrderStatusAccepted {
|
||
return fmt.Errorf("目前只支持待拣货状态前的订单售前调整!")
|
||
}
|
||
orderSku := orderSkus[0]
|
||
if orderSku.Count > 1 {
|
||
orderSku.Count--
|
||
_, err = dao.UpdateEntity(db, orderSku, "Count")
|
||
} else {
|
||
_, err = dao.DeleteEntity(db, orderSku)
|
||
}
|
||
order.AdjustCount++
|
||
order.ActualPayPrice = order.ActualPayPrice - orderSku.SalePrice
|
||
order.TotalShopMoney = int64(float64(order.ActualPayPrice) * jdshopapi.JdsPayPercentage)
|
||
dao.UpdateEntity(db, order, "AdjustCount", "TotalShopMoney")
|
||
return err
|
||
}
|
||
|
||
func UpdateWaybillDesiredFee(ctx *jxcontext.Context, vendorOrderID string, desiredFee int) (err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
)
|
||
order, _ := dao.GetSimpleOrder(db, vendorOrderID)
|
||
if order == nil {
|
||
return fmt.Errorf("未找到该订单!orderID: %v", vendorOrderID)
|
||
}
|
||
bill, _ := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID)
|
||
if bill == nil {
|
||
waybill := &model.Waybill{
|
||
VendorOrderID: order.VendorOrderID,
|
||
OrderVendorID: order.VendorID,
|
||
VendorWaybillID: utils.Int64ToStr(GenOrderNo(ctx)),
|
||
WaybillVendorID: -1,
|
||
Status: model.WaybillStatusDelivered,
|
||
WaybillCreatedAt: time.Now(),
|
||
StatusTime: time.Now(),
|
||
WaybillFinishedAt: utils.DefaultTimeValue,
|
||
DeliveryFlag: model.OrderDeliveryFlagMaskScheduleDisabled,
|
||
DesiredFee: int64(desiredFee),
|
||
}
|
||
dao.CreateEntity(db, waybill)
|
||
order.VendorWaybillID = waybill.VendorWaybillID
|
||
dao.UpdateEntity(db, order, "VendorWaybillID")
|
||
} else {
|
||
bill.DesiredFee = int64(desiredFee)
|
||
_, err = dao.UpdateEntity(db, bill, "DesiredFee")
|
||
if order.EarningType == model.EarningTypePoints {
|
||
order.NewEarningPrice = order.NewEarningPrice - int64(desiredFee)
|
||
_, err = dao.UpdateEntity(db, order, "NewEarningPrice")
|
||
}
|
||
}
|
||
return err
|
||
}
|
||
|
||
func AcceptOrRefuseOrder(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isAccept bool) (err error) {
|
||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
||
handler := partner.GetPurchaseOrderHandlerFromVendorID(vendorID)
|
||
err = handler.AcceptOrRefuseOrder(order, isAccept, ctx.GetUserName())
|
||
if err == nil && isAccept && vendorID == model.VendorIDEBAI {
|
||
// netprinter.PrintOrderByOrder(jxcontext.AdminCtx, order)
|
||
// smsmsg.NotifyNewOrder(order)
|
||
// smsmsg.NotifyNewUserOrder(order)
|
||
// weixinmsg.NotifyNewOrder(order)
|
||
// msghub.OnNewOrder(order)
|
||
}
|
||
return err
|
||
}
|
||
|
||
func GenOrderNo(ctx *jxcontext.Context) (orderNo int64) {
|
||
const prefix = 88
|
||
const randPartNum = 1000
|
||
orderNo = time.Now().Unix() - orderNoBeginTimestamp
|
||
// fmt.Println(orderNo)
|
||
orderNo = orderNo * randPartNum
|
||
md5Bytes := md5.Sum([]byte(utils.GetUUID()))
|
||
randPart := 0
|
||
for k, v := range md5Bytes {
|
||
randPart += int(v) << ((k % 3) * 8)
|
||
}
|
||
orderNo += int64(randPart % randPartNum)
|
||
orderNo += int64(math.Pow10(int(math.Log10(float64(orderNo)))+1)) * prefix
|
||
return orderNo
|
||
}
|
||
|
||
func RefreshJdsOrderConsigneeInfo(ctx *jxcontext.Context, vendorOrderID string) (err error) {
|
||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJDShop)
|
||
if order == nil {
|
||
return fmt.Errorf("未查询到此京东商城订单!")
|
||
}
|
||
waybill, err := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID)
|
||
if waybill != nil {
|
||
return fmt.Errorf("已经创建了三方运单不允许修改联系人信息!")
|
||
}
|
||
jdsOrder, err := jdshop.GetJdsOrder(order.VendorOrderID2, order.VendorOrgCode)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if jdsOrder == nil {
|
||
return fmt.Errorf("未查询到对应的京东商城订单!")
|
||
}
|
||
order.ConsigneeAddress = jdshop.Decrypt(jdsOrder.ConsigneeInfo.FullAddress, order.VendorOrgCode)
|
||
order.ConsigneeName = jdshop.Decrypt(jdsOrder.ConsigneeInfo.Fullname, order.VendorOrgCode)
|
||
order.ConsigneeMobile = jdshop.Decrypt(jdsOrder.ConsigneeInfo.Mobile, order.VendorOrgCode)
|
||
order.ConsigneeMobile2 = jdshop.Decrypt(jdsOrder.ConsigneeInfo.Telephone, order.VendorOrgCode)
|
||
order.BuyerComment = jdsOrder.OrderRemark
|
||
if order.ConsigneeAddress != "" {
|
||
lng, lat, _ := api.AutonaviAPI.GetCoordinateFromAddress(order.ConsigneeAddress, "")
|
||
order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng)
|
||
order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat)
|
||
}
|
||
partner.CurOrderManager.UpdateOrderFields(order, []string{"ConsigneeAddress", "ConsigneeName", "ConsigneeMobile", "ConsigneeMobile2", "BuyerComment", "ConsigneeLng", "ConsigneeLat"})
|
||
return err
|
||
}
|
||
|
||
func UpdateOrderInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, payload map[string]interface{}) (num int64, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
)
|
||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
||
if payload["consigneeLng"] != nil || payload["consigneeLat"] != nil {
|
||
payload["consigneeLng"] = jxutils.StandardCoordinate2Int(utils.Interface2Float64WithDefault(payload["consigneeLng"], 0.0))
|
||
payload["consigneeLat"] = jxutils.StandardCoordinate2Int(utils.Interface2Float64WithDefault(payload["consigneeLat"], 0.0))
|
||
}
|
||
if payload["expectedDeliveredTime"] != nil {
|
||
payload["expectedDeliveredTime"] = utils.Str2Time(payload["expectedDeliveredTime"].(string))
|
||
}
|
||
valid := dao.StrictMakeMapByStructObject(payload, order, ctx.GetUserName())
|
||
if len(valid) > 0 {
|
||
txDB, _ := dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db, txDB)
|
||
panic(r)
|
||
}
|
||
}()
|
||
if num, err = dao.UpdateEntityByKV(db, order, valid, nil); err != nil {
|
||
dao.Rollback(db, txDB)
|
||
return 0, err
|
||
}
|
||
dao.Commit(db, txDB)
|
||
}
|
||
return num, err
|
||
}
|
||
|
||
func RefreshOrderSkuInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID, skuID int) (num int64, err error) {
|
||
var (
|
||
db = dao.GetDB()
|
||
shopPrice, earningPrice int64
|
||
)
|
||
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID)
|
||
if order.EarningType != model.EarningTypeQuote {
|
||
return 0, fmt.Errorf("目前只支持报价订单有此操作!")
|
||
}
|
||
updateOrderSku := func(v *model.OrderSku, skuID2 int) (err error) {
|
||
storeSkus, _ := dao.GetStoresSkusInfo(db, []int{jxutils.GetSaleStoreIDFromOrder(order)}, []int{skuID2})
|
||
if len(storeSkus) == 0 {
|
||
return fmt.Errorf("未找到此门店商品!")
|
||
}
|
||
storeSku := storeSkus[0]
|
||
//if v.ShopPrice == v.EarningPrice {
|
||
if beego.BConfig.RunMode == "jxgy" {
|
||
if v.SalePrice > v.ShopPrice {
|
||
v.EarningPrice = int64(math.Round(float64(storeSku.Price) * float64(order.OrderPayPercentage) / 100))
|
||
}
|
||
} else {
|
||
v.EarningPrice = int64(math.Round(float64(storeSku.Price) * float64(order.OrderPayPercentage) / 100))
|
||
}
|
||
//}
|
||
v.ShopPrice = int64(storeSku.Price)
|
||
dao.UpdateEntity(db, v, "ShopPrice", "EarningPrice")
|
||
return err
|
||
}
|
||
txDB, _ := dao.Begin(db)
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
dao.Rollback(db, txDB)
|
||
panic(r)
|
||
}
|
||
}()
|
||
for _, v := range order.Skus {
|
||
if v.SkuID == 0 {
|
||
if v.SkuID == skuID {
|
||
err = updateOrderSku(v, skuID)
|
||
}
|
||
} else {
|
||
if v.JxSkuID == skuID {
|
||
err = updateOrderSku(v, skuID)
|
||
}
|
||
}
|
||
}
|
||
if err != nil {
|
||
return 0, err
|
||
}
|
||
for _, v := range order.Skus {
|
||
shopPrice += v.ShopPrice * int64(v.Count)
|
||
earningPrice += v.EarningPrice * int64(v.Count)
|
||
}
|
||
order.ShopPrice = shopPrice
|
||
order.EarningPrice = earningPrice
|
||
num, err = dao.UpdateEntity(db, order, "ShopPrice", "EarningPrice")
|
||
dao.Commit(db, txDB)
|
||
return num, err
|
||
}
|
||
|
||
func SaveJdsOrders(ctx *jxcontext.Context, orderCreatedStart, orderCreatedEnd time.Time) (err error) {
|
||
var (
|
||
pageSize = 20
|
||
)
|
||
orderResult, err := jdshop.CurPurchaseHandler.GetJdsOrders(ctx, utils.Time2Str(orderCreatedStart), utils.Time2Str(orderCreatedEnd), 1, pageSize)
|
||
if err != nil {
|
||
noticeMsg := fmt.Sprintf("京东商城保存订单出错!(多半是cookie过期了),err :[%v]", err)
|
||
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "BF09DB25350611EB89AC525400E86DC0", "cookie", noticeMsg)
|
||
return err
|
||
}
|
||
orders, err := result2Orders(ctx, orderResult)
|
||
if orderResult.TotalCount > pageSize {
|
||
for pageNO := 2; pageNO < orderResult.TotalCount/pageSize+1; pageNO++ {
|
||
orderResult, _ := jdshop.CurPurchaseHandler.GetJdsOrders(ctx, utils.Time2Str(orderCreatedStart), utils.Time2Str(orderCreatedEnd), pageNO, pageSize)
|
||
orders2, _ := result2Orders(ctx, orderResult)
|
||
orders = append(orders, orders2...)
|
||
}
|
||
}
|
||
for _, order := range orders {
|
||
order.StoreID = 100000
|
||
order.JxStoreID = 100000
|
||
order.StoreName = "商城模板店2"
|
||
order.VendorStoreID = model.JdShopMainVendorStoreID
|
||
partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order))
|
||
globals.SugarLogger.Debugf("SaveJdsOrders, order: [%v]", utils.Format4Output(order, false))
|
||
noticeMsg := fmt.Sprintf("京东商城新订单,订单号:[%v] ,将要发到的门店id:[%v] , 门店名:[%v]", order.VendorOrderID, order.StoreID, order.StoreName)
|
||
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "BF09DB25350611EB89AC525400E86DC0", "京东商城来新订单了!", noticeMsg)
|
||
// ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "1439B3E07D3911EA881A525400E86DC0", "京东商城来新订单了!", noticeMsg)
|
||
}
|
||
return err
|
||
}
|
||
|
||
func result2Orders(ctx *jxcontext.Context, result *jdshopapi.AllOrdersResult) (orders []*model.GoodsOrder, err error) {
|
||
for _, jdsOrder := range result.OrderList {
|
||
//等待付款的排除
|
||
if jdsOrder.OrderStatus != jdshopapi.JdsOrderStatusWaittingExport && jdsOrder.OrderStatus != jdshopapi.JdsOrderStatusPause && jdsOrder.OrderStatus != 51 {
|
||
continue
|
||
}
|
||
//有可能是库里已经有这个订单了
|
||
orderE, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(jdsOrder.OrderID)+"000001", model.VendorIDJDShop)
|
||
if orderE != nil {
|
||
continue
|
||
}
|
||
|
||
orderDetail, err := jdshop.GetAPI("2").OrderDetail(utils.Int64ToStr(jdsOrder.OrderID))
|
||
if err != nil {
|
||
globals.SugarLogger.Debugf("jds OrderDetail error: %v", err.Error())
|
||
continue
|
||
}
|
||
order := &model.GoodsOrder{
|
||
VendorOrderID2: utils.Int64ToStr(jdsOrder.OrderID),
|
||
VendorOrderID: utils.Int64ToStr(jdsOrder.OrderID) + "000001",
|
||
VendorID: model.VendorIDJDShop,
|
||
BaseFreightMoney: jxutils.StandardPrice2Int(jdsOrder.Freight),
|
||
VendorStatus: utils.Int2Str(jdsOrder.OrderStatus),
|
||
VendorUserID: jdsOrder.UserPin,
|
||
BuyerComment: jdsOrder.UserRemark,
|
||
PickDeadline: utils.DefaultTimeValue,
|
||
OriginalData: string(utils.MustMarshal(jdsOrder)),
|
||
StoreName: jdsOrder.StoreName,
|
||
OrderCreatedAt: utils.Str2Time(jdsOrder.OrderCreateTime + ":00"),
|
||
ConsigneeAddress: orderDetail.ConsigneeAddress,
|
||
ConsigneeName: orderDetail.ConsigneeName,
|
||
ActualPayPrice: orderDetail.ActualPayPrice,
|
||
Status: model.OrderStatusNew,
|
||
TotalShopMoney: utils.Float64TwoInt64(math.Round(utils.Int64ToFloat64(orderDetail.ActualPayPrice) * jdshopapi.JdsPayPercentage)),
|
||
DeliveryFlag: model.OrderDeliveryFlagMaskScheduleDisabled,
|
||
DeliveryType: model.OrderDeliveryTypeStoreSelf,
|
||
StatusTime: utils.Str2Time(jdsOrder.OrderCreateTime + ":00"),
|
||
OrderSeq: 0,
|
||
VendorOrgCode: "2",
|
||
}
|
||
//获取真实手机号
|
||
fakeMobile, err := jdshop.GetAPI("2").PhoneSensltiveInfo(order.VendorOrderID2, orderDetail.MobileKey)
|
||
if err != nil {
|
||
globals.SugarLogger.Debugf("jds PhoneSensltiveInfo error: %v", err.Error())
|
||
continue
|
||
} else {
|
||
order.ConsigneeMobile = jxutils.DecryptDESECB([]byte(fakeMobile), []byte(jdshopapi.JdsMobileKey))
|
||
}
|
||
if order.TotalShopMoney < 100 {
|
||
order.TotalShopMoney = 100
|
||
}
|
||
if order.ConsigneeAddress != "" {
|
||
lng, lat, _ := api.AutonaviAPI.GetCoordinateFromAddress(order.ConsigneeAddress, "")
|
||
order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng)
|
||
order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat)
|
||
}
|
||
// storeList, err := common.GetStoreListByLocation(ctx, jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), 5000, false, true, 0)
|
||
// if err != nil {
|
||
// globals.SugarLogger.Debugf("jds GetStoreListByLocation error: %v", err.Error())
|
||
// continue
|
||
// }
|
||
// order.StoreID = storeList[0].ID
|
||
// order.StoreName = storeList[0].Name
|
||
// storeMaps, _ := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDJDShop}, []int{order.StoreID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "", "")
|
||
// if len(storeMaps) > 0 {
|
||
// order.VendorStoreID = storeMaps[0].VendorStoreID
|
||
// }
|
||
//如果是暂停,表示是预订单
|
||
if jdsOrder.OrderStatus == jdshopapi.JdsOrderStatusPause {
|
||
order.BusinessType = model.BusinessTypeDingshida
|
||
order.ExpectedDeliveredTime = utils.Str2Time(orderDetail.ExpectedDeliveredTime)
|
||
order.PickDeadline = order.ExpectedDeliveredTime.Add(-time.Hour)
|
||
} else if jdsOrder.OrderStatus != jdshopapi.JdsOrderStatusWaittingPayDel {
|
||
order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
|
||
order.BusinessType = model.BusinessTypeImmediate
|
||
}
|
||
// else {
|
||
// globals.SugarLogger.Errorf("未知的京东商城订单状态!status : %v", jdsOrder.OrderStatus)
|
||
// }
|
||
|
||
//结算类型
|
||
// storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), order.StoreID, model.VendorIDJDShop, "")
|
||
// if storeDetail != nil {
|
||
// if storeDetail.PayPercentage < 50 {
|
||
// order.EarningType = model.EarningTypePoints
|
||
// } else {
|
||
// order.EarningType = model.EarningTypeQuote
|
||
// }
|
||
// }
|
||
setJdsOrderSeq(order)
|
||
for _, v := range jdsOrder.OrderItems {
|
||
sku := &model.OrderSku{
|
||
VendorID: model.VendorIDJDShop,
|
||
VendorOrderID: order.VendorOrderID,
|
||
Count: v.SkuNum,
|
||
VendorSkuID: utils.Int64ToStr(v.SkuID),
|
||
SkuName: v.SkuName,
|
||
VendorPrice: jxutils.StandardPrice2Int(v.JdPrice),
|
||
SalePrice: jxutils.StandardPrice2Int(v.JdPrice),
|
||
}
|
||
var storeSku *model.StoreSkuBind
|
||
sql := `
|
||
SELECT * FROM store_sku_bind WHERE store_id = ? AND jds_id = ? AND deleted_at = ?
|
||
`
|
||
sqlParams := []interface{}{model.JdShopMainStoreID, v.SkuID, utils.DefaultTimeValue}
|
||
err = dao.GetRow(dao.GetDB(), &storeSku, sql, sqlParams)
|
||
if storeSku != nil {
|
||
sku.SkuID = storeSku.SkuID
|
||
}
|
||
_, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.SkuName)
|
||
sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit)
|
||
order.Skus = append(order.Skus, sku)
|
||
}
|
||
orders = append(orders, order)
|
||
}
|
||
return orders, err
|
||
}
|