@@ -8,6 +8,7 @@ import (
"time"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxcallback/auth/weixin"
"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"
@@ -71,6 +72,13 @@ type SkuSaleInfo struct {
Count int // 销售的总份数
}
type StoreOpRequestInfo struct {
model . StoreOpRequest
StoreName string
SkuNamePrefix string
SkuNameName string
}
// 商品不可售,直接排除
// 如果门店商品是可售状态,那么会忽略区域限制。否则有区域限制
func GetStoreSkus ( ctx * jxcontext . Context , storeID int , isFocus bool , keyword string , params map [ string ] interface { } , offset , pageSize int ) ( skuNamesInfo * StoreSkuNamesInfo , err error ) {
@@ -426,10 +434,15 @@ func checkStoresSkusSaleCity(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs []i
}
func updateStoresSkusWithoutSync ( ctx * jxcontext . Context , storeIDs [ ] int , skuBindInfos [ ] * StoreSkuBindInfo ) ( needSyncSkus [ ] int , err error ) {
globals . SugarLogger . Debugf ( "updateStoresSkusWithoutSync, storeIDs:%v, skuBindInfos:%s" , storeIDs , utils . Format4Output ( skuBindInfos , false ) )
db := dao . GetDB ( )
if err = checkStoresSkusSaleCity ( ctx , db , storeIDs , skuBindInfos ) ; err != nil {
return nil , err
}
if storeIDs , skuBindInfos , err = filterStorePriceChange ( ctx , storeIDs , skuBindInfos ) ; err != nil {
return nil , err
}
userName := ctx . GetUserName ( )
needSyncIDMap := make ( map [ int ] int )
dao . Begin ( db )
@@ -450,7 +463,7 @@ func updateStoresSkusWithoutSync(ctx *jxcontext.Context, storeIDs []int, skuBind
JOIN sku_name t3 ON t1.name_id = t3.id AND t3.deleted_at = ?
WHERE t1.name_id = ? AND t1.deleted_at = ?
` , storeID , utils . DefaultTimeValue , utils . DefaultTimeValue , skuBindInfo . NameID , utils . DefaultTimeValue ) ; err == nil {
globals. SugarLogger. Debug ( utils . Format4Output( allBinds, false ) )
// globals. SugarLogger.Debug(utils. Format4Output( allBinds, false) )
inSkuBinsMap := make ( map [ int ] * StoreSkuBindSkuInfo , len ( inSkuBinds ) )
for _ , v := range inSkuBinds {
inSkuBinsMap [ v . SkuID ] = v
@@ -832,6 +845,214 @@ func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID, toStoreID int, copyMode
return num , err
}
func shouldPendingStorePriceChange ( ctx * jxcontext . Context , storeID int , skuBindInfo * StoreSkuBindInfo ) bool {
return globals . EnablePendingChange && ctx . GetLoginType ( ) == weixin . LoginType
}
func filterStorePriceChange ( ctx * jxcontext . Context , storeIDs [ ] int , skuBindInfos [ ] * StoreSkuBindInfo ) ( filteredStoreIDs [ ] int , filteredSkuBindInfos [ ] * StoreSkuBindInfo , err error ) {
globals . SugarLogger . Debug ( "filterStorePriceChange" )
if globals . EnablePendingChange {
db := dao . GetDB ( )
dao . Begin ( db )
defer dao . Rollback ( db )
for _ , storeID := range storeIDs {
for _ , skuBindInfo := range skuBindInfos {
shouldPending := shouldPendingStorePriceChange ( ctx , storeID , skuBindInfo )
if shouldPending {
changeReq := & model . StoreOpRequest {
Type : model . RequestTypeChangePrice ,
StoreID : storeID ,
ItemID : skuBindInfo . NameID ,
Status : model . RequestStatusNew ,
UserID : ctx . GetUserName ( ) ,
IntParam1 : skuBindInfo . UnitPrice ,
IntParam2 : skuBindInfo . IsSale ,
}
if skuBindInfo . IsFocus == 1 {
changeReq . Type = model . RequestTypeFocusSkuName
}
if len ( skuBindInfo . Skus ) > 0 {
changeReq . JsonParam = string ( utils . MustMarshal ( skuBindInfo . Skus ) )
}
dao . WrapAddIDCULDEntity ( changeReq , ctx . GetUserName ( ) )
if err = dao . CreateOrUpdate ( db , changeReq ) ; err != nil {
return nil , nil , err
}
// 去除价格相关的部分
if skuBindInfo . IsFocus == 1 {
skuBindInfo . IsFocus = 0
}
skuBindInfo . UnitPrice = 0
}
}
}
dao . Commit ( db )
}
return storeIDs , skuBindInfos , nil
}
func AcceptStoreOpRequests ( ctx * jxcontext . Context , reqIDs [ ] int ) ( err error ) {
if globals . EnablePendingChange {
if len ( reqIDs ) > 0 {
subErrors := make ( map [ int ] error )
db := dao . GetDB ( )
for _ , reqID := range reqIDs {
op := & model . StoreOpRequest { }
op . ID = reqID
if err2 := dao . GetEntity ( db , op ) ; err2 != nil {
subErrors [ reqID ] = err2
} else {
if op . Status == model . RequestStatusNew {
skuBindInfo := & StoreSkuBindInfo {
NameID : op . ItemID ,
UnitPrice : op . IntParam1 ,
IsSale : op . IntParam2 ,
}
if op . Type == model . RequestTypeFocusSkuName {
skuBindInfo . IsFocus = 1
}
if op . JsonParam != "" {
if err2 = utils . UnmarshalUseNumber ( [ ] byte ( op . JsonParam ) , & skuBindInfo . Skus ) ; err2 != nil {
subErrors [ reqID ] = err2
}
}
if err2 == nil {
_ , err2 := UpdateStoresSkus ( ctx , [ ] int { op . StoreID } , [ ] * StoreSkuBindInfo { skuBindInfo } )
isLocalSucess := true
if err2 != nil {
subErrors [ reqID ] = err2
if ! isSyncError ( err2 ) {
isLocalSucess = false
}
}
if isLocalSucess {
if err2 := changeStoreOpStatus ( ctx , [ ] int { reqID } , model . RequestStatusAccepted , "" ) ; err2 != nil {
subErrors [ reqID ] = err2
}
}
}
}
}
}
if len ( subErrors ) > 0 {
errMsg := ""
for k , v := range subErrors {
errMsg += fmt . Sprintf ( "req:%d, error:%s\n" , k , v . Error ( ) )
}
err = errors . New ( errMsg )
}
}
}
return err
}
func RejectStoreOpRequests ( ctx * jxcontext . Context , reqIDs [ ] int , rejectReason string ) ( err error ) {
return changeStoreOpStatus ( ctx , reqIDs , model . RequestStatusRejected , rejectReason )
}
// 当前些函数只针对type为: RequestTypeChangePrice与RequestTypeFocusSkuName的查询才有效
func GetStoreOpRequests ( ctx * jxcontext . Context , fromTime , toTime time . Time , keyword string , params map [ string ] interface { } , offset , pageSize int ) ( requestList [ ] * StoreOpRequestInfo , err error ) {
if globals . EnablePendingChange {
sql := `
SELECT t1.id, t1.created_at, t1.updated_at, t1.last_operator, t1.deleted_at,
t1.type, t1.store_id, t1.item_id, t1.status, t1.user_id, t1.int_param1, t1.int_param2,
t2.name store_name, t3.prefix sku_name_prefix, t3.name sku_name_name, AVG(t5.unit_price) unit_price
FROM store_op_request t1
JOIN store t2 ON t1.store_id = t2.id
JOIN sku_name t3 ON t1.item_id = t3.id
JOIN sku t4 ON t3.id = t4.name_id
LEFT JOIN store_sku_bind t5 ON t1.store_id = t5.store_id AND t4.id = t5.sku_id AND t5.deleted_at = ?
WHERE t1.created_at >= ? AND t1.created_at <= ?
`
sqlParams := [ ] interface { } {
utils . DefaultTimeValue ,
fromTime ,
toTime ,
}
if keyword != "" {
keywordLike := "%" + keyword + "%"
sql += " AND ( t2.name LIKE ? OR t3.name LIKE ?"
sqlParams = append ( sqlParams , keywordLike , keywordLike )
if keywordInt64 , err2 := strconv . ParseInt ( keyword , 10 , 64 ) ; err2 == nil {
sql += " OR t1.store_id = ? OR t1.item_id = ?"
sqlParams = append ( sqlParams , keywordInt64 , keywordInt64 )
}
sql += ")"
}
if params [ "storeIDs" ] != nil {
var storeIDs [ ] int
if err = utils . UnmarshalUseNumber ( [ ] byte ( params [ "storeIDs" ] . ( string ) ) , & storeIDs ) ; err != nil {
return nil , err
}
if len ( storeIDs ) > 0 {
sql += " AND t1.store_id IN (" + dao . GenQuestionMarks ( len ( storeIDs ) ) + ")"
sqlParams = append ( sqlParams , storeIDs )
}
}
if params [ "types" ] != nil {
var typeList [ ] int
if err = utils . UnmarshalUseNumber ( [ ] byte ( params [ "types" ] . ( string ) ) , & typeList ) ; err != nil {
return nil , err
}
if len ( typeList ) > 0 {
sql += " AND t1.type IN (" + dao . GenQuestionMarks ( len ( typeList ) ) + ")"
sqlParams = append ( sqlParams , typeList )
}
}
if params [ "statuss" ] != nil {
var statusList [ ] int
if err = utils . UnmarshalUseNumber ( [ ] byte ( params [ "statuss" ] . ( string ) ) , & statusList ) ; err != nil {
return nil , err
}
if len ( statusList ) > 0 {
sql += " AND t1.status IN (" + dao . GenQuestionMarks ( len ( statusList ) ) + ")"
sqlParams = append ( sqlParams , statusList )
}
}
sql += `
GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
LIMIT ? OFFSET ? `
pageSize = jxutils . FormalizePageSize ( pageSize )
sqlOffset := offset
sqlPageSize := pageSize
sqlParams = append ( sqlParams , sqlPageSize , sqlOffset )
db := dao . GetDB ( )
// globals.SugarLogger.Debug(sql)
// globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false))
if err = dao . GetRows ( db , & requestList , sql , sqlParams ... ) ; err == nil {
return requestList , nil
}
}
return nil , err
}
func changeStoreOpStatus ( ctx * jxcontext . Context , reqIDs [ ] int , status int8 , rejectReason string ) ( err error ) {
globals . SugarLogger . Debugf ( "changeStoreOpStatus, reqIDs:%v" , reqIDs )
if globals . EnablePendingChange {
if len ( reqIDs ) > 0 {
db := dao . GetDB ( )
dao . Begin ( db )
defer dao . Rollback ( db )
for _ , reqID := range reqIDs {
op := & model . StoreOpRequest { }
op . Remark = rejectReason
op . Status = status
dao . WrapUpdateULEntity ( op , ctx . GetUserName ( ) )
op . DeletedAt = time . Now ( )
op . ID = reqID
// globals.SugarLogger.Debug(utils.Format4Output(op, false))
if _ , err = dao . UpdateEntity ( db , op , "Remark" , "Status" , "DeletedAt" , "LastOperator" , "UpdatedAt" ) ; err != nil {
return err
}
}
dao . Commit ( db )
}
}
return err
}
func setStoreSkuBindStatus ( skuBind * model . StoreSkuBind , status int8 ) {
skuBind . JdSyncStatus |= status
skuBind . ElmSyncStatus |= status