This commit is contained in:
苏尹岚
2021-02-25 17:18:09 +08:00
parent 966a11f394
commit 8f1d5a72d4
7 changed files with 120 additions and 26 deletions

View File

@@ -853,6 +853,9 @@ func (s *DefScheduler) createWaybillOn3rdProviders(savedOrderInfo *WatchOrderInf
}
}
}
//1表示为门店发单需要验证门店账户余额情况
_, err = s.CheckStoreBalance(jxcontext.AdminCtx, order, waybillVendorIDs)
//TODO 2021-02-19 增加品牌配送开关
if storeDetail.BrandIsOpen == model.YES {
err = fmt.Errorf("此品牌已关闭配送! [%v]", storeDetail.BrandName)

View File

@@ -5,6 +5,8 @@ import (
"math"
"time"
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model/dao"
@@ -130,6 +132,36 @@ func (s *DefScheduler) CreateWaybillOnProviders4SavedOrder(ctx *jxcontext.Contex
if forceCreate {
s.stopTimer(savedOrderInfo)
}
//门店发单开始扣钱
if order.CreateDeliveryType == model.YES {
//暂时这么认为len courierVendorIDs 为1表示是老板或者运营从小程序上点的立即发单因为小程序上是点哪个发哪个
//京西后台则是点一下发3个len courierVendorIDs 是0
//如果是小程序上点哪个扣哪个平台的钱
//如果是后台,则选最高的那个扣
var deliveryDee int64
deliveryFeeMap, _ := s.QueryOrderWaybillFeeInfoEx(ctx, order.VendorOrderID, order.VendorID)
if len(courierVendorIDs) == 1 {
courierVendorID := courierVendorIDs[0]
if _, ok := deliveryFeeMap[courierVendorID]; ok {
deliveryDee = deliveryFeeMap[courierVendorID].DeliveryFee
}
} else if len(courierVendorIDs) == 0 {
var maxFee int64
for _, v := range deliveryFeeMap {
if v.DeliveryFee > maxFee {
v.DeliveryFee = maxFee
}
}
deliveryDee = maxFee
}
handler := partner.CurStoreAcctManager
//此订单没有因为发运单而扣除过门店账户
if isExist, err := handler.CheckStoreAcctExpendExist(jxutils.GetSaleStoreIDFromOrder(order), partner.StoreAcctTypeExpendCreateWaybillEx, order.VendorOrderID); err == nil && !isExist {
err = handler.InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order), int(deliveryDee), partner.StoreAcctTypeExpendCreateWaybillEx, order.VendorOrderID)
} else if isExist {
globals.SugarLogger.Debugf("CreateWaybillOnProviders4SavedOrder orderID:%s userName:%s ,storeAcctExpend isExist", order.VendorOrderID, ctx.GetUserName())
}
}
globals.SugarLogger.Debugf("CreateWaybillOnProviders4SavedOrder orderID:%s userName:%s successfully", order.VendorOrderID, ctx.GetUserName())
return bills, err
}
@@ -141,7 +173,15 @@ func (s *DefScheduler) CreateWaybillOnProviders4SavedOrder(ctx *jxcontext.Contex
return nil, err
}
func (s *DefScheduler) CreateWaybillOnProvidersEx(ctx *jxcontext.Context, vendorOrderID string, vendorID int, courierVendorIDs []int, forceCreate bool, maxDeliveryFee int64) (bills []*model.Waybill, err error) {
func (s *DefScheduler) CreateWaybillOnProvidersEx(ctx *jxcontext.Context, vendorOrderID string, vendorID int, courierVendorIDs []int, forceCreate bool, maxDeliveryFee int64) (bills []*model.Waybill, errCode string, err error) {
savedOrderInfo := s.loadSavedOrderByID(vendorOrderID, vendorID, true)
if savedOrderInfo != nil {
order := savedOrderInfo.order
//1表示为门店发单需要验证门店账户余额情况
if errCode, err = s.CheckStoreBalance(ctx, order, courierVendorIDs); err != nil {
return nil, errCode, err
}
}
jxutils.CallMsgHandler(func() {
bills, err = func() (bills []*model.Waybill, err error) {
userName := ctx.GetUserName()
@@ -155,18 +195,6 @@ func (s *DefScheduler) CreateWaybillOnProvidersEx(ctx *jxcontext.Context, vendor
if order.DeliveryType == model.OrderDeliveryTypeSelfTake {
return nil, fmt.Errorf("订单:%s是自提单", vendorOrderID)
}
//1表示为门店发单需要验证门店账户余额情况
if order.CreateDeliveryType == model.YES {
//暂时这么认为len courierVendorIDs 为1表示是老板或者运营从小程序上点的立即发单因为小程序上是点哪个发哪个
//京西后台则是点一下发3个len courierVendorIDs 是0
//如果是小程序上点哪个扣哪个平台的钱
//如果是后台,则选最高的那个扣
if len(courierVendorIDs) == 1 {
} else if len(courierVendorIDs) == 0 {
}
}
if !forceCreate {
err = s.isPossibleSwitch2SelfDelivery(order)
}
@@ -188,7 +216,43 @@ func (s *DefScheduler) CreateWaybillOnProvidersEx(ctx *jxcontext.Context, vendor
return bills, err
}()
}, jxutils.ComposeUniversalOrderID(vendorOrderID, vendorID))
return bills, err
return bills, errCode, err
}
func (s *DefScheduler) CheckStoreBalance(ctx *jxcontext.Context, order *model.GoodsOrder, courierVendorIDs []int) (errCode string, err error) {
if order.CreateDeliveryType == model.YES {
//暂时这么认为len courierVendorIDs 为1表示是老板或者运营从小程序上点的立即发单因为小程序上是点哪个发哪个
//京西后台则是点一下发3个len courierVendorIDs 是0
//如果是小程序上点哪个扣哪个平台的钱
//如果是后台,则选最高的那个扣
storeAcct, err := cms.GetStoreAcctBalance(ctx, jxutils.GetSaleStoreIDFromOrder(order))
deliveryFeeMap, _ := s.QueryOrderWaybillFeeInfoEx(ctx, order.VendorOrderID, order.VendorID)
if err != nil {
return errCode, fmt.Errorf("获取账户余额失败!")
}
if storeAcct.AccountBalance < partner.MinCreateWaybillBalance {
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店账户余额小于[%v]元,不能发配送!", jxutils.IntPrice2Standard(partner.MinCreateWaybillBalance))
}
if len(courierVendorIDs) == 1 {
courierVendorID := courierVendorIDs[0]
if _, ok := deliveryFeeMap[courierVendorID]; ok {
if deliveryFeeMap[courierVendorID].DeliveryFee > int64(storeAcct.AccountBalance) {
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店账户余额小于[%v]元,不能发配送!", jxutils.IntPrice2Standard(deliveryFeeMap[courierVendorID].DeliveryFee))
}
}
} else if len(courierVendorIDs) == 0 {
var maxFee int64
for _, v := range deliveryFeeMap {
if v.DeliveryFee > maxFee {
v.DeliveryFee = maxFee
}
}
if maxFee > int64(storeAcct.AccountBalance) {
return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店账户余额小于[%v]元,不能发配送!", jxutils.IntPrice2Standard(maxFee))
}
}
}
return errCode, err
}
// todo 这个函数可以和SelfDeliveringAndUpdateStatus合并

View File

@@ -1,6 +1,7 @@
package cms
import (
"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"
@@ -86,9 +87,11 @@ func (s *StoreAcctManager) InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx *j
var (
db = dao.GetDB()
)
if err = s.InsertStoreAcctExpend(ctx, db, storeID, price, acctType, vendorOrderID); err == nil {
s.UpdateStoreAcctBalance(ctx, storeID, price, false)
}
utils.CallFuncAsync(func() {
if err = s.InsertStoreAcctExpend(ctx, db, storeID, price, acctType, vendorOrderID); err == nil {
s.UpdateStoreAcctBalance(ctx, storeID, price, false)
}
})
return err
}
@@ -96,12 +99,21 @@ func (s *StoreAcctManager) InsertStoreAcctIncomeAndUpdateStoreAcctBalance(ctx *j
var (
db = dao.GetDB()
)
if err = s.InsertStoreAcctIncome(ctx, db, storeID, price, acctType); err == nil {
s.UpdateStoreAcctBalance(ctx, storeID, price, true)
}
utils.CallFuncAsync(func() {
if err = s.InsertStoreAcctIncome(ctx, db, storeID, price, acctType); err == nil {
s.UpdateStoreAcctBalance(ctx, storeID, price, true)
}
})
return err
}
func (s *StoreAcctManager) CheckStoreAcctExpendExist(storeID int, vendorOrderID string) (result bool, err error) {
func (s *StoreAcctManager) CheckStoreAcctExpendExist(storeID, acctType int, vendorOrderID string) (result bool, err error) {
var (
db = dao.GetDB()
)
//暂时这样,后应该会再查有没有对冲的入账记录来判断
if results, err := dao.GetStoreAcctExpend(db, storeID, acctType, vendorOrderID, utils.ZeroTimeValue, utils.ZeroTimeValue); err == nil && len(results) > 0 {
return true, err
}
return false, err
}

View File

@@ -1035,7 +1035,7 @@ func GetStoreAcctIncomeTotal(db *DaoDB, storeID, incomeType int, fromTime, toTim
return income.IncomePrice, err
}
func GetStoreAcctExpend(db *DaoDB, storeID, expendType int, fromTime, toTime time.Time) (storeAcctExpends []*model.StoreAcctExpend, err error) {
func GetStoreAcctExpend(db *DaoDB, storeID, expendType int, vendorOrderID string, fromTime, toTime time.Time) (storeAcctExpends []*model.StoreAcctExpend, err error) {
sql := `
SELECT *
FROM store_acct_expend
@@ -1050,6 +1050,10 @@ func GetStoreAcctExpend(db *DaoDB, storeID, expendType int, fromTime, toTime tim
sql += " AND type = ?"
sqlParams = append(sqlParams, expendType)
}
if vendorOrderID != "" {
sql += " AND vendor_order_id = ?"
sqlParams = append(sqlParams, vendorOrderID)
}
if utils.IsTimeZero(fromTime) {
sql += " AND created_at >= ?"
sqlParams = append(sqlParams, fromTime)

View File

@@ -17,6 +17,9 @@ const (
ErrCodeJsonActEarningPriceIsZero = "-103"
ErrCodeJsonUserAlreadyExist = "-104" // 用户已经存在错,且能成功登录
ErrCodeJsonSyncErr = "-105"
ErrCodeAccountBalanceNotEnough = "-201" //余额不足
ErrCodeNotAuthBindWeixin = "-202" //没有绑定微信认证方式
)
var (

View File

@@ -6,7 +6,15 @@ import (
)
const (
StoreAcctType1 = 1 //主动充值
//账户收入类型
StoreAcctTypeIncomePay = 1 //主动充值
//账户支出类型
StoreAcctTypeExpendCreateWaybillEx = 2 //手动发单扣除的临时运费
)
const (
MinCreateWaybillBalance = 1000 //余额小于这个值直接不能发
)
var (
@@ -26,5 +34,5 @@ type IStoreAcctManager interface {
UpdateStoreAcctBalance(ctx *jxcontext.Context, storeID, price int, isIncome bool) (err error)
InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx *jxcontext.Context, storeID, price, acctType int, vendorOrderID string) (err error)
InsertStoreAcctIncomeAndUpdateStoreAcctBalance(ctx *jxcontext.Context, storeID, price, acctType int) (err error)
CheckStoreAcctExpendExist(storeID int, vendorOrderID string) (result bool, err error)
CheckStoreAcctExpendExist(storeID, acctType int, vendorOrderID string) (result bool, err error)
}

View File

@@ -124,9 +124,9 @@ func (c *OrderController) CreateWaybillOnProviders() {
c.callCreateWaybillOnProviders(func(params *tOrderCreateWaybillOnProvidersParams) (retVal interface{}, errCode string, err error) {
var courierVendorIDs []int
if err = jxutils.Strings2Objs(params.CourierVendorIDs, &courierVendorIDs); err == nil {
retVal, err = defsch.FixedScheduler.CreateWaybillOnProvidersEx(params.Ctx, params.VendorOrderID, params.VendorID, courierVendorIDs, params.ForceCreate, int64(params.MaxDeliveryFee))
retVal, errCode, err = defsch.FixedScheduler.CreateWaybillOnProvidersEx(params.Ctx, params.VendorOrderID, params.VendorID, courierVendorIDs, params.ForceCreate, int64(params.MaxDeliveryFee))
}
return retVal, "", err
return retVal, errCode, err
})
}