diff --git a/business/jxcallback/scheduler/defsch/defsch_ext.go b/business/jxcallback/scheduler/defsch/defsch_ext.go index 9f43aa67f..f5b4d68cb 100644 --- a/business/jxcallback/scheduler/defsch/defsch_ext.go +++ b/business/jxcallback/scheduler/defsch/defsch_ext.go @@ -233,6 +233,11 @@ func (s *DefScheduler) CheckStoreBalance(ctx *jxcontext.Context, order *model.Go if storeAcct.AccountBalance < partner.MinCreateWaybillBalance { return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("门店账户余额小于[%v]元,不能发配送!", jxutils.IntPrice2Standard(partner.MinCreateWaybillBalance)) } + //1、先判断是不是第一次发:查询库里是否有这个订单的运费支出记录,再查询是否有相同金额并且类型为回退的收入记录(取消运单退回) + //前者有,后者无, 表示已经发过了,暂未取消,若这这次的发单金额小于上次的金额则不进行判断也不多扣钱,若大于则扣除‘这次金额-上次金额’的钱,余额不足问题也根据这个判断 + //前者有,后者有,表示发过并且取消过了,是多次发,直接扣 + //前者无,表示就是第一次发,直接扣 + //2、小程序里这次金额用发单平台的金额,后台里这次金额用所有平台最高费用 if len(courierVendorIDs) == 1 { courierVendorID := courierVendorIDs[0] if _, ok := deliveryFeeMap[courierVendorID]; ok { diff --git a/business/jxstore/cms/store_acct.go b/business/jxstore/cms/store_acct.go index 29a0639f6..9543bc59f 100644 --- a/business/jxstore/cms/store_acct.go +++ b/business/jxstore/cms/store_acct.go @@ -20,27 +20,57 @@ func init() { partner.InitStoreAcctManager(FixedStoreAcctManager) } -func (s *StoreAcctManager) InsertStoreAcctIncome(ctx *jxcontext.Context, db *dao.DaoDB, storeID, price, acctType int) (err error) { +func (s *StoreAcctManager) InsertStoreAcctIncome(ctx *jxcontext.Context, db *dao.DaoDB, storeID, price, acctType int, vendorOrderID string) (err error) { + var ( + userID, userName string + ) + if ctx != nil { + userID = ctx.GetUserID() + userName = ctx.GetUserName() + } else { + storeOrder := &model.StoreAcctOrder{ + VendorOrderID: vendorOrderID, + } + if err = dao.GetEntity(db, storeOrder, "VendorOrderID"); err == nil && storeOrder.ID != 0 { + userID = storeOrder.UserID + userName = storeOrder.LastOperator + } + } storeAcctIncome := &model.StoreAcctIncome{ StoreID: storeID, IncomePrice: price, Type: acctType, - UserID: ctx.GetUserID(), + UserID: userID, } - dao.WrapAddIDCULEntity(storeAcctIncome, ctx.GetUserName()) + dao.WrapAddIDCULEntity(storeAcctIncome, userName) err = dao.CreateEntity(db, storeAcctIncome) return err } func (s *StoreAcctManager) InsertStoreAcctExpend(ctx *jxcontext.Context, db *dao.DaoDB, storeID, price, acctType int, vendorOrderID string) (err error) { + var ( + userID, userName string + ) + if ctx != nil { + userID = ctx.GetUserID() + userName = ctx.GetUserName() + } else { + storeOrder := &model.StoreAcctOrder{ + VendorOrderID: vendorOrderID, + } + if err = dao.GetEntity(db, storeOrder, "VendorOrderID"); err == nil && storeOrder.ID != 0 { + userID = storeOrder.UserID + userName = storeOrder.LastOperator + } + } storeAcctExpend := &model.StoreAcctExpend{ StoreID: storeID, ExpendPrice: price, Type: acctType, - UserID: ctx.GetUserID(), + UserID: userID, VendorOrderID: vendorOrderID, } - dao.WrapAddIDCULEntity(storeAcctExpend, ctx.GetUserName()) + dao.WrapAddIDCULEntity(storeAcctExpend, userName) err = dao.CreateEntity(db, storeAcctExpend) return err } @@ -49,6 +79,9 @@ func (s *StoreAcctManager) UpdateStoreAcctBalance(ctx *jxcontext.Context, storeI var ( db = dao.GetDB() ) + if ctx == nil { + ctx = jxcontext.AdminCtx + } storeAcct := &model.StoreAcct{ StoreID: storeID, } @@ -95,12 +128,12 @@ func (s *StoreAcctManager) InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx *j return err } -func (s *StoreAcctManager) InsertStoreAcctIncomeAndUpdateStoreAcctBalance(ctx *jxcontext.Context, storeID, price, acctType int) (err error) { +func (s *StoreAcctManager) InsertStoreAcctIncomeAndUpdateStoreAcctBalance(ctx *jxcontext.Context, storeID, price, acctType int, vendorOrderID string) (err error) { var ( db = dao.GetDB() ) utils.CallFuncAsync(func() { - if err = s.InsertStoreAcctIncome(ctx, db, storeID, price, acctType); err == nil { + if err = s.InsertStoreAcctIncome(ctx, db, storeID, price, acctType, vendorOrderID); err == nil { s.UpdateStoreAcctBalance(ctx, storeID, price, true) } }) diff --git a/business/model/order.go b/business/model/order.go index c667aa4ee..f2e358cea 100644 --- a/business/model/order.go +++ b/business/model/order.go @@ -11,9 +11,11 @@ const ( ) const ( - PayTypeWX = 1 // 微信支付 - PayTypeTL = 2 // 通联宝支付 + PayTypeWX = 1 // 微信支付 + PayTypeTL = 2 // 通联宝支付 + PayTypeTL_DiscountCard = 3 // 通联宝支付(会员折扣卡) + PayTypeTL_StoreAcctPay = 4 // 通联宝支付(门店账户充值) PayStatusNo = 0 PayStatusYes = 1 @@ -485,6 +487,25 @@ func (v *StoreCoupons) TableIndex() [][]string { } } +type StoreAcctOrder struct { + ModelIDCUL + + VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + StoreID int `orm:"column(store_id)" json:"storeID"` // 外部系统里记录的 jxstoreid + ActualPayPrice int `json:"actualPayPrice"` // 单位为分 顾客实际支付 + UserID string `orm:"column(user_id);size(48);index" json:"userID"` + OrderType int `json:"orderType"` + Status int `json:"status"` // 参见OrderStatus*相关的常量定义 // 重复新订单消息数,这个一般不是由于消息重发造成的(消息重发由OrderStatus过滤),一般是业务逻辑造成的 + OrderFinishedAt time.Time `orm:"type(datetime)" json:"orderFinishedAt"` +} + +func (v *StoreAcctOrder) TableUnique() [][]string { + return [][]string{ + []string{"VendorOrderID", "VendorID"}, + } +} + // 判断是否是购买平台自有物流 // 对于京东,饿百来说,就是其自有的物流,对于微商城来说,是达达 func IsWaybillPlatformOwn(bill *Waybill) bool { diff --git a/business/partner/partner_store_acct.go b/business/partner/partner_store_acct.go index e913c8d04..98b9d7d2a 100644 --- a/business/partner/partner_store_acct.go +++ b/business/partner/partner_store_acct.go @@ -27,12 +27,12 @@ func InitStoreAcctManager(curStoreManager IStoreAcctManager) { type IStoreAcctManager interface { //增加一条收入流水 - InsertStoreAcctIncome(ctx *jxcontext.Context, db *dao.DaoDB, storeID, price, acctType int) (err error) + InsertStoreAcctIncome(ctx *jxcontext.Context, db *dao.DaoDB, storeID, price, acctType int, vendorOrderID string) (err error) //增加一条支出流水 InsertStoreAcctExpend(ctx *jxcontext.Context, db *dao.DaoDB, storeID, price, acctType int, vendorOrderID string) (err error) //更新门店账户 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) + InsertStoreAcctIncomeAndUpdateStoreAcctBalance(ctx *jxcontext.Context, storeID, price, acctType int, vendorOrderID string) (err error) CheckStoreAcctExpendExist(storeID, acctType int, vendorOrderID string) (result bool, err error) } diff --git a/business/partner/purchase/jx/localjx/order.go b/business/partner/purchase/jx/localjx/order.go index 24c5d3e16..258251039 100644 --- a/business/partner/purchase/jx/localjx/order.go +++ b/business/partner/purchase/jx/localjx/order.go @@ -388,6 +388,21 @@ func Pay4User(ctx *jxcontext.Context, thingID int, vendorOrderID string, payType dao.UpdateEntity(db, userMemberOrigin, "EndAt") } } + case model.PayTypeTL_StoreAcctPay: + storeOrder := &model.StoreAcctOrder{ + VendorOrderID: vendorOrderID, + } + if err = dao.GetEntity(db, storeOrder, "VendorOrderID"); err == nil && storeOrder.ID != 0 { + order = &model.GoodsOrder{ + VendorOrderID: vendorOrderID, + ActualPayPrice: int64(storeOrder.ActualPayPrice), + VendorID: model.VendorIDJX, + } + if orderPay, err = pay4OrderByTL(ctx, order, payType, vendorPayType); err == nil && orderPay != nil { + dao.WrapAddIDCULDEntity(orderPay, ctx.GetUserName()) + err = dao.CreateEntity(dao.GetDB(), orderPay) + } + } default: err = fmt.Errorf("支付方式:%d当前不支持", payType) } @@ -543,6 +558,17 @@ func OnPayFinished(orderPay *model.OrderPay) (err error) { dao.UpdateEntity(dao.GetDB(), userMembers[0], "IsPay") err = nil } + case model.PayTypeTL_StoreAcctPay: //门店账户充值完成后直接入账 + storeOrder := &model.StoreAcctOrder{ + VendorOrderID: orderPay.VendorOrderID, + } + if err = dao.GetEntity(dao.GetDB(), storeOrder, "VendorOrderID"); err == nil && storeOrder.ID != 0 { + storeOrder.OrderFinishedAt = time.Now() + storeOrder.Status = model.OrderStatusFinished + if _, err = dao.UpdateEntity(dao.GetDB(), storeOrder, "OrderFinishedAt", "Status"); err == nil { + partner.CurStoreAcctManager.InsertStoreAcctIncomeAndUpdateStoreAcctBalance(nil, storeOrder.StoreID, storeOrder.ActualPayPrice, partner.StoreAcctTypeIncomePay, orderPay.VendorOrderID) + } + } default: priceDefendOrders, _ := dao.GetPriceDefendOrder(dao.GetDB(), orderPay.VendorOrderID, nil, nil, []int{jxutils.GetDefendPriceIssue()}, 0, -1, -1, 0, "", utils.ZeroTimeValue, utils.ZeroTimeValue, false) if len(priceDefendOrders) > 0 { @@ -2443,16 +2469,16 @@ func CreateStoreAcctOrder(ctx *jxcontext.Context, orderType, storeID, price int) dao.CreateEntity(db, storeAcct) } - order := &model.GoodsOrder{ + order := &model.StoreAcctOrder{ VendorOrderID: utils.Int64ToStr(jxutils.GenOrderNo()), UserID: ctx.GetUserID(), StoreID: storeID, OrderType: orderType, Status: model.OrderStatusWait4Pay, - ActualPayPrice: int64(price), - OrderCreatedAt: time.Now(), + ActualPayPrice: price, VendorID: model.VendorIDJX, } + dao.WrapAddIDCULEntity(order, ctx.GetUserName()) dao.Begin(db) defer func() { if r := recover(); r != nil { diff --git a/globals/beegodb/beegodb.go b/globals/beegodb/beegodb.go index 6a7568054..66b2805b7 100644 --- a/globals/beegodb/beegodb.go +++ b/globals/beegodb/beegodb.go @@ -104,6 +104,7 @@ func Init() { orm.RegisterModel(&model.StoreAcct{}) orm.RegisterModel(&model.StoreAcctExpend{}) orm.RegisterModel(&model.StoreAcctIncome{}) + orm.RegisterModel(&model.StoreAcctOrder{}) // create table orm.RunSyncdb("default", false, true)