Merge branch 'mark' into get-store

This commit is contained in:
gazebo
2019-06-24 21:43:41 +08:00
33 changed files with 1229 additions and 766 deletions

View File

@@ -236,29 +236,6 @@ func (c *OrderManager) SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao
return isDuplicated, err
}
func getPromotionSkuPriceMap(db *dao.DaoDB, storeID int, skuIDs []int) (skuPriceMap map[int64]*model.PromotionSku, err error) {
sql := `
SELECT t3.*
FROM promotion t1
JOIN promotion_store t2 ON t2.promotion_id = t1.id AND t2.store_id = ?
JOIN promotion_sku t3 ON t3.promotion_id = t1.id AND t3.sku_id IN (` + dao.GenQuestionMarks(len(skuIDs)) + `) AND t3.earning_price > 0
WHERE t1.deleted_at = ? AND (t1.status = ? OR t1.status = ?) AND (t1.begin_at <= NOW() AND t1.end_at >= NOW()) AND t1.vendor_id = ?`
var skuPriceList []*model.PromotionSku
if err = dao.GetRows(db, &skuPriceList, sql, storeID, skuIDs, utils.DefaultTimeValue, model.PromotionStatusLocalCreated, model.PromotionStatusRemoteCreated, model.VendorIDJX); err != nil {
return nil, err
}
skuPriceMap = make(map[int64]*model.PromotionSku)
for _, v := range skuPriceList {
if v.EarningPrice > 0 {
index := jxutils.Combine2Int(v.SkuID, v.Price)
if skuPriceMap[index] == nil || v.EarningPrice < skuPriceMap[index].EarningPrice {
skuPriceMap[index] = v
}
}
}
return skuPriceMap, err
}
func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.DaoDB) (err error) {
globals.SugarLogger.Debugf("updateOrderSkuOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID)
jxStoreID := jxutils.GetShowStoreIDFromOrder(order)
@@ -309,12 +286,14 @@ func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.
skumapper[v.VendorSkuID] = v
}
skuPriceMap, err2 := getPromotionSkuPriceMap(db, jxStoreID, jxutils.IntMap2List(skuIDMap))
if err = err2; err != nil {
globals.SugarLogger.Errorf("updateOrderSkuOtherInfo can not get sku promotion info for orderID:%s, error:%v", order.VendorOrderID, err)
return err
var skuPriceMap map[int64]*dao.PromotionStoreSku
if len(skuIDMap) > 0 {
skuPriceMap, err = dao.GetPromotionSkuPriceMap(db, model.VendorIDJX, []int{jxStoreID}, jxutils.IntMap2List(skuIDMap), time.Now(), time.Now())
if err != nil {
globals.SugarLogger.Errorf("updateOrderSkuOtherInfo can not get sku promotion info for orderID:%s, error:%v", order.VendorOrderID, err)
return err
}
}
for _, v := range orderSkus {
v.VendorOrderID = order.VendorOrderID
v.VendorID = order.VendorID
@@ -335,10 +314,12 @@ func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.
}
}
if skuID := jxutils.GetSkuIDFromOrderSku(v); skuID > 0 && v.StoreSubName != "" {
index := jxutils.Combine2Int(jxStoreID, int(v.SalePrice))
if skuPriceMap[index] != nil {
v.EarningPrice = int64(skuPriceMap[index].EarningPrice)
if skuPriceMap != nil {
if skuID := jxutils.GetSkuIDFromOrderSku(v); skuID > 0 /*&& v.StoreSubName != ""*/ {
index := dao.GenSkuPriceMapKey(jxStoreID, v.SkuID)
if skuPriceMap[index] != nil && skuPriceMap[index].EarningPrice > 0 {
v.EarningPrice = int64(skuPriceMap[index].EarningPrice)
}
}
}
}
@@ -349,22 +330,37 @@ func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.
func (c *OrderManager) updateOrderOtherInfo(order *model.GoodsOrder, db *dao.DaoDB) (err error) {
globals.SugarLogger.Debugf("updateOrderOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID)
storeMap := &model.StoreMap{
VendorID: order.VendorID,
VendorStoreID: order.VendorStoreID,
payPercentage := 0
storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, order.VendorStoreID, order.VendorID)
if err != nil {
globals.SugarLogger.Warnf("updateOrderOtherInfo GetStoreDetailByVendorStoreID orderID:%s, VendorStoreID:%s, error:%v", order.VendorOrderID, order.VendorStoreID, err)
if !dao.IsNoRowsError(err) {
return err
}
err = nil
} else {
order.JxStoreID = storeDetail.Store.ID
payPercentage = storeDetail.PayPercentage
}
storeMap.DeletedAt = utils.DefaultTimeValue
if err = dao.GetEntity(db, storeMap, model.FieldVendorID, model.FieldVendorStoreID, model.FieldDeletedAt); err != nil && err != orm.ErrNoRows {
globals.SugarLogger.Warnf("updateOrderOtherInfo GetEntity orderID:%s, VendorStoreID:%s, error:%v", order.VendorOrderID, order.VendorStoreID, err)
return err
}
order.JxStoreID = storeMap.StoreID
if err = c.updateOrderSkuOtherInfo(order, db); err == nil {
jxutils.RefreshOrderSkuRelated(order)
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 {
@@ -516,9 +512,18 @@ func (c *OrderManager) UpdateOrderStatusAndDeliveryFlag(order *model.GoodsOrder)
}
func (c *OrderManager) UpdateOrderFields(order *model.GoodsOrder, fieldList []string) (err error) {
db := orm.NewOrm()
db := dao.GetDB()
utils.CallFuncLogError(func() error {
_, err = db.Update(order, fieldList...)
if order.ID == 0 {
order2 := *order
if err = dao.GetEntity(db, &order2, model.FieldVendorOrderID, model.FieldVendorID); err == nil {
order.ID = order2.ID
}
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

View File

@@ -74,94 +74,66 @@ func (c *OrderManager) GetOrderSkuInfo(ctx *jxcontext.Context, vendorOrderID str
if vendorID == model.VendorIDJD {
fullSkuNameSQL = "CONCAT(t1.sku_name, IF(t3.is_spu = 1 AND LOCATE(';', t1.sku_name) = 0, CONCAT('[约', t2.spec_quality, t2.spec_unit, '/', t3.unit, ']'), ''))"
}
sql := fmt.Sprintf(`
SELECT
t1.id,
t1.vendor_order_id,
t1.vendor_id,
t1.count,
t1.vendor_sku_id,
t1.sku_id,
t1.jx_sku_id,
t1.sku_name,
IF(t1.shop_price = 0, t1.sale_price, t1.shop_price) shop_price,
t1.sale_price,
t1.earning_price,
CAST(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t5.pay_percentage > 0, t5.pay_percentage, %d) / 100) AS SIGNED) real_earning_price,
t1.weight,
t1.sku_type,
t1.promotion_type,
t1.order_created_at,
t1.store_sub_id,
t1.store_sub_name,
t1.vendor_price,
%s full_sku_name,
`, model.DefaultEarningPricePercentage, fullSkuNameSQL)
db := dao.GetDB()
if vendorID == model.VendorIDELM {
err = dao.GetRows(db, &skus, fmt.Sprintf(`
SELECT
t1.id,
t1.vendor_order_id,
t1.vendor_id,
t1.count,
t1.vendor_sku_id,
t1.sku_id,
t1.jx_sku_id,
t1.sku_name,
IF(t1.shop_price = 0, t1.sale_price, t1.shop_price) shop_price,
t1.sale_price,
t1.earning_price,
t1.weight,
t1.sku_type,
t1.promotion_type,
t1.order_created_at,
t1.store_sub_id,
t1.store_sub_name,
t1.vendor_price,
IF(t3.img IS NULL OR t3.img = '', t4.col_imageUrl, t3.img) image, %s full_sku_name
FROM order_sku t1
LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/
LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
LEFT JOIN ede_skus t4 ON t1.vendor_sku_id = t4.col_id
WHERE vendor_order_id = ? AND vendor_id = ?
ORDER BY t1.sku_name
`, fullSkuNameSQL), /*, utils.DefaultTimeValue, utils.DefaultTimeValue*/ vendorOrderID, vendorID)
err = dao.GetRows(db, &skus, sql+`
IF(t3.img <> '', t3.img, t4.col_imageUrl) image
FROM order_sku t1
LEFT JOIN goods_order t6 ON t6.vendor_order_id = t1.vendor_order_id AND t6.vendor_id = t1.vendor_id
LEFT JOIN store t5 ON t5.id = IF(t6.jx_store_id <> 0, t6.jx_store_id, t6.store_id)
LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/
LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
LEFT JOIN ede_skus t4 ON t1.vendor_sku_id = t4.col_id
WHERE t1.vendor_order_id = ? AND t1.vendor_id = ?
ORDER BY t1.sku_name
`, /*, utils.DefaultTimeValue, utils.DefaultTimeValue*/ vendorOrderID, vendorID)
} else if vendorID == model.VendorIDJD {
err = dao.GetRows(db, &skus, fmt.Sprintf(`
SELECT
t1.id,
t1.vendor_order_id,
t1.vendor_id,
t1.count,
t1.vendor_sku_id,
t1.sku_id,
t1.jx_sku_id,
t1.sku_name,
IF(t1.shop_price = 0, t1.sale_price, t1.shop_price) shop_price,
t1.sale_price,
t1.earning_price,
t1.weight,
t1.sku_type,
t1.promotion_type,
t1.order_created_at,
t1.store_sub_id,
t1.store_sub_name,
t1.vendor_price,
IF(t3.img IS NULL OR t3.img = '', t4.image, t3.img) image, %s full_sku_name
FROM order_sku t1
LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/
LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
LEFT JOIN jde_sku_infos t4 ON t1.vendor_sku_id = t4.skuId
WHERE vendor_order_id = ? AND vendor_id = ?
ORDER BY t1.sku_name
`, fullSkuNameSQL), /*, utils.DefaultTimeValue, utils.DefaultTimeValue*/ vendorOrderID, vendorID)
err = dao.GetRows(db, &skus, sql+`
IF(t3.img <> '', t3.img, t4.image) image
FROM order_sku t1
LEFT JOIN goods_order t6 ON t6.vendor_order_id = t1.vendor_order_id AND t6.vendor_id = t1.vendor_id
LEFT JOIN store t5 ON t5.id = IF(t6.jx_store_id <> 0, t6.jx_store_id, t6.store_id)
LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/
LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
LEFT JOIN jde_sku_infos t4 ON t1.vendor_sku_id = t4.skuId
WHERE t1.vendor_order_id = ? AND t1.vendor_id = ?
ORDER BY t1.sku_name
`, /*, utils.DefaultTimeValue, utils.DefaultTimeValue*/ vendorOrderID, vendorID)
}
if err != nil || len(skus) == 0 {
err = dao.GetRows(db, &skus, fmt.Sprintf(`
SELECT
t1.id,
t1.vendor_order_id,
t1.vendor_id,
t1.count,
t1.vendor_sku_id,
t1.sku_id,
t1.jx_sku_id,
t1.sku_name,
IF(t1.shop_price = 0, t1.sale_price, t1.shop_price) shop_price,
t1.sale_price,
t1.earning_price,
t1.weight,
t1.sku_type,
t1.promotion_type,
t1.order_created_at,
t1.store_sub_id,
t1.store_sub_name,
t1.vendor_price,
t3.img image, %s full_sku_name
FROM order_sku t1
LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/
LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
WHERE t1.vendor_order_id = ? AND t1.vendor_id = ?
ORDER BY t1.sku_name
`, fullSkuNameSQL), /*, utils.DefaultTimeValue, utils.DefaultTimeValue*/ vendorOrderID, vendorID)
err = dao.GetRows(db, &skus, sql+`
t3.img image
FROM order_sku t1
LEFT JOIN goods_order t6 ON t6.vendor_order_id = t1.vendor_order_id AND t6.vendor_id = t1.vendor_id
LEFT JOIN store t5 ON t5.id = IF(t6.jx_store_id <> 0, t6.jx_store_id, t6.store_id)
LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/
LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/
WHERE t1.vendor_order_id = ? AND t1.vendor_id = ?
ORDER BY t1.sku_name
`, /*, utils.DefaultTimeValue, utils.DefaultTimeValue*/ vendorOrderID, vendorID)
if err != nil {
globals.SugarLogger.Infof("GetOrderSkuInfo orderID:%s vendorID:%d failed with error:%v", vendorOrderID, vendorID, err)
return nil, err
@@ -281,14 +253,18 @@ func (c *OrderManager) getOrders(ctx *jxcontext.Context, isIncludeSku bool, from
if offset < 0 {
offset = 0
}
sql := `
sql := fmt.Sprintf(`
SELECT SQL_CALC_FOUND_ROWS t1.*,
CAST(IF(t1.shop_price <= t1.vendor_price, IF(t1.shop_price = 0, t1.sale_price, t1.shop_price), IF(t1.vendor_price = 0, t1.sale_price, t1.vendor_price))*IF(t5.pay_percentage IS NULL OR t5.pay_percentage <= 0, 70, t5.pay_percentage)/100 AS SIGNED) earning_price,
CAST(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t5.pay_percentage > 0, t5.pay_percentage, %d) / 100) AS SIGNED) earning_price,
t2.status waybill_status, t2.courier_name, t2.courier_mobile,
t2.actual_fee, t2.desired_fee, t2.waybill_created_at, t2.waybill_finished_at`
t2.actual_fee, t2.desired_fee, t2.waybill_created_at, t2.waybill_finished_at`, model.DefaultEarningPricePercentage)
if isIncludeSku {
sql += `,
t3.sku_id, t3.count sku_count2, t3.shop_price sku_shop_price, IF(t3.earning_price <> 0, t3.earning_price, t3.sale_price) sku_sale_price`
t3.sku_id,
t3.count sku_count2,
t3.shop_price sku_shop_price,
t3.earning_price sku_earning_price,
t3.sale_price sku_sale_price`
}
sql += `
FROM goods_order t1
@@ -475,6 +451,7 @@ func (c *OrderManager) ExportOrders(ctx *jxcontext.Context, fromDateStr, toDateS
utils.Int2Str(v.SkuCount2),
utils.Int2Str(v.SkuShopPrice),
utils.Int2Str(v.SkuSalePrice),
utils.Int2Str(v.SkuEarningPrice),
}, ",")
if order == nil || v.ID != order.ID {
order = v
@@ -780,14 +757,14 @@ func (c *OrderManager) GetStoresOrderSaleInfo(ctx *jxcontext.Context, storeIDLis
return nil, fmt.Errorf("查询时间范围不能超过60天")
}
// 用int64类型去取float型的数据库返回值会取不到
sql := `
sql := fmt.Sprintf(`
SELECT IF(t1.jx_store_id > 0, t1.jx_store_id, t1.store_id) store_id, t1.vendor_id, IF(t1.status < ?, 0, t1.status) status,
COUNT(*) count, SUM(t1.shop_price) shop_price, SUM(t1.vendor_price) vendor_price, SUM(t1.sale_price) sale_price, SUM(t1.actual_pay_price) actual_pay_price,
CAST(SUM(IF(t1.shop_price <= t1.vendor_price, IF(t1.shop_price = 0, t1.sale_price, t1.shop_price), IF(t1.vendor_price = 0, t1.sale_price, t1.vendor_price))*IF(t5.pay_percentage IS NULL OR t5.pay_percentage <= 0, 70, t5.pay_percentage)/100) AS SIGNED) earning_price
CAST(SUM(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t5.pay_percentage > 0, t5.pay_percentage, %d) / 100)) AS SIGNED) earning_price
FROM goods_order t1
LEFT JOIN store t5 ON t5.id = IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id)
WHERE t1.order_created_at >= ? AND t1.order_created_at <= ?
`
`, model.DefaultEarningPricePercentage)
sqlParams := []interface{}{
model.OrderStatusEndBegin,
fromTime,

View File

@@ -1,16 +1,13 @@
package act
import (
"fmt"
"time"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
)
@@ -25,35 +22,17 @@ type ActOrderRuleParam struct {
}
type ActStoreSkuParam struct {
model.ActStoreSku
Action int // -1删除1修改2新增
StoreID int `orm:"column(store_id)" json:"storeID"`
SkuID int `orm:"column(sku_id)" json:"skuID"`
PricePercentage int `orm:"" json:"pricePercentage"` // 单品级活动用SKU级的价格比例非0覆盖Act中的PricePercentage
ActPrice int64 `orm:"" json:"actPrice"` // 单品级活动用SKU级指定的价格非0覆盖CustomPricePercentage与Act中的PricePercentage
Stock int `orm:"" json:"stock"` // 订单级活动用
}
type ActDetail struct {
model.Act2
}
func ActStoreSkuParam2Map(actStoreSku []*ActStoreSkuParam) (actStoreSkuMap map[int][]*ActStoreSkuParam) {
if len(actStoreSku) > 0 {
for _, v := range actStoreSku {
actStoreSkuMap[v.StoreID] = append(actStoreSkuMap[v.StoreID], v)
}
}
return actStoreSkuMap
}
func genStoreSkuMapKey(storeID, skuID int) int64 {
return int64(storeID) + int64(skuID)*1000000
}
func ActStoreSkuParam2Model(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actStoreSku []*ActStoreSkuParam) (actMapList []*model.ActMap, actStoreMapList []*model.ActStoreMap, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap, err error) {
func ActStoreSkuParam2Model(ctx *jxcontext.Context, db *dao.DaoDB, act *model.Act, vendorIDs []int, actStoreSku []*ActStoreSkuParam) (validVendorIDs []int, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap, err error) {
wholeValidVendorMap := make(map[int]int)
if len(actStoreSku) > 0 {
storeIDMap := make(map[int]int)
skuIDMap := make(map[int]int)
@@ -63,18 +42,16 @@ func ActStoreSkuParam2Model(ctx *jxcontext.Context, act *model.Act, vendorIDs []
skuIDMap[v.SkuID] = 1
storeSkuParamMap[v.StoreID] = append(storeSkuParamMap[v.StoreID], v)
}
db := dao.GetDB()
storeSkuList, err2 := dao.GetStoresSkusInfo(db, jxutils.IntMap2List(storeIDMap), jxutils.IntMap2List(skuIDMap))
if err = err2; err != nil {
return nil, nil, nil, nil, err
return nil, nil, nil, err
}
storeSkuMap := make(map[int64]*model.StoreSkuBind)
for _, v := range storeSkuList {
storeSkuMap[genStoreSkuMapKey(v.StoreID, v.SkuID)] = v
storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v
}
wholeValidVendorMap := make(map[int]int)
for storeID, oneStoreSkuParam := range storeSkuParamMap {
validVendorMap := make(map[int]int)
validSkuMap := make(map[int]int)
@@ -82,7 +59,7 @@ func ActStoreSkuParam2Model(ctx *jxcontext.Context, act *model.Act, vendorIDs []
storeDetail, err2 := dao.GetStoreDetail(db, storeID, vendorID)
if err = err2; err == nil {
for _, v := range oneStoreSkuParam {
if storeSkuInfo := storeSkuMap[genStoreSkuMapKey(v.StoreID, v.SkuID)]; storeSkuInfo != nil {
if storeSkuInfo := storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]; storeSkuInfo != nil {
validVendorMap[vendorID] = 1
validSkuMap[v.SkuID] = 1
actSkuMap := &model.ActStoreSkuMap{
@@ -107,64 +84,31 @@ func ActStoreSkuParam2Model(ctx *jxcontext.Context, act *model.Act, vendorIDs []
actStoreSkuMapList = append(actStoreSkuMapList, actSkuMap)
}
}
wholeValidVendorMap[vendorID] = 1
} else if !dao.IsNoRowsError(err) {
return nil, nil, nil, nil, err
return nil, nil, nil, err
} else {
err = nil
}
}
for _, v := range oneStoreSkuParam {
if validSkuMap[v.SkuID] == 1 {
if storeSkuInfo := storeSkuMap[genStoreSkuMapKey(v.StoreID, v.SkuID)]; storeSkuInfo != nil {
storeSku := &model.ActStoreSku{
ActID: act.ID,
StoreID: v.StoreID,
SkuID: v.SkuID,
OriginalPrice: int64(storeSkuInfo.Price),
PricePercentage: v.PricePercentage,
ActPrice: v.ActPrice,
Stock: v.Stock,
}
if validSkuMap[v.SkuID] == 1 { // todo 这里是否需要判断
if storeSkuInfo := storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]; storeSkuInfo != nil {
storeSku := &v.ActStoreSku
storeSku.ActID = act.ID
storeSku.OriginalPrice = int64(storeSkuInfo.Price)
dao.WrapAddIDCULDEntity(storeSku, ctx.GetUserName())
actStoreSkuList = append(actStoreSkuList, storeSku)
}
}
}
for vendorID := range validVendorMap {
wholeValidVendorMap[vendorID] = 1
actStoreMap := &model.ActStoreMap{
ActID: act.ID,
StoreID: storeID,
VendorID: vendorID,
SyncStatus: model.SyncFlagNewMask,
}
dao.WrapAddIDCULDEntity(actStoreMap, ctx.GetUserName())
actStoreMapList = append(actStoreMapList, actStoreMap)
}
}
for vendorID := range wholeValidVendorMap {
actMap := &model.ActMap{
ActID: act.ID,
VendorID: vendorID,
SyncStatus: model.SyncFlagNewMask,
}
dao.WrapAddIDCULDEntity(actMap, ctx.GetUserName())
actMapList = append(actMapList, actMap)
}
}
return actMapList, actStoreMapList, actStoreSkuList, actStoreSkuMapList, err
return jxutils.IntMap2List(wholeValidVendorMap), actStoreSkuList, actStoreSkuMapList, err
}
func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (actID int, err error) {
vendorIDMap := make(map[int]bool)
for _, v := range vendorIDs {
vendorIDMap[v] = true
}
db := dao.GetDB()
dao.WrapAddIDCULDEntity(act, ctx.GetUserName())
func addActStoreBind(ctx *jxcontext.Context, db *dao.DaoDB, actStoreSkuList []*model.ActStoreSku, actStoreSkuMapList []*model.ActStoreSkuMap) (err error) {
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
@@ -172,32 +116,108 @@ func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRules
panic(r)
}
}()
err = dao.CreateEntity(db, act)
if err != nil {
return 0, err
storeSkuMap := make(map[int64]int)
for _, v := range actStoreSkuList {
err = dao.CreateEntity(db, v)
if err != nil {
dao.Rollback(db)
return err
}
storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v.ID
}
actMapList, actStoreMapList, actStoreSkuList, actStoreSkuMapList, err := ActStoreSkuParam2Model(ctx, act, vendorIDs, actStoreSku)
if err != nil {
return 0, err
for _, v := range actStoreSkuMapList {
v.BindID = storeSkuMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]
}
isEmptyAct := true
for _, list := range []interface{}{
actMapList, actStoreMapList, actStoreSkuList, actStoreSkuMapList,
} {
if len(utils.Interface2Slice(list)) > 0 {
err = dao.CreateMultiEntities(db, list)
if err != nil {
dao.Rollback(db)
return 0, err
}
isEmptyAct = false
if len(actStoreSkuMapList) > 0 {
err = dao.CreateMultiEntities(db, actStoreSkuMapList)
if err != nil {
dao.Rollback(db)
return err
}
}
if isEmptyAct {
dao.Commit(db)
return err
}
func AddActStoreBind(ctx *jxcontext.Context, actID int, actStoreSku []*ActStoreSkuParam) (err error) {
db := dao.GetDB()
var vendorIDs []int
actMap, err := dao.GetActVendorInfo(db, actID, nil)
if err != nil {
return err
}
for vendorID := range actMap {
vendorIDs = append(vendorIDs, vendorID)
}
var act *model.Act
if len(vendorIDs) > 0 {
act = &actMap[vendorIDs[0]].Act
} else {
act = &model.Act{}
act.ID = actID
if err = dao.GetEntity(db, act); err != nil {
return err
}
}
_, actStoreSkuList, actStoreSkuMapList, err := ActStoreSkuParam2Model(ctx, db, act, vendorIDs, actStoreSku)
if err != nil {
return err
}
err = addActStoreBind(ctx, db, actStoreSkuList, actStoreSkuMapList)
return err
}
func CreateAct(ctx *jxcontext.Context, act *model.Act, vendorIDs []int, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (actID int, err error) {
db := dao.GetDB()
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db)
panic(r)
}
}()
dao.WrapAddIDCULDEntity(act, ctx.GetUserName())
err = dao.CreateEntity(db, act)
if err != nil {
dao.Rollback(db)
return 0, fmt.Errorf("没有门店及SKU满足需求空操作")
return 0, err
}
validVendorIDs, actStoreSkuList, actStoreSkuMapList, err := ActStoreSkuParam2Model(ctx, db, act, vendorIDs, actStoreSku)
if err != nil {
return 0, err
}
var actMapList []*model.ActMap
for vendorID := range validVendorIDs {
actMap := &model.ActMap{
ActID: act.ID,
VendorID: vendorID,
SyncStatus: model.SyncFlagNewMask,
}
dao.WrapAddIDCULDEntity(actMap, ctx.GetUserName())
actMapList = append(actMapList, actMap)
}
if len(actMapList) > 0 {
err = dao.CreateMultiEntities(db, actMapList)
if err != nil {
dao.Rollback(db)
return 0, err
}
}
if err = addActStoreBind(ctx, db, actStoreSkuList, actStoreSkuMapList); err != nil {
dao.Rollback(db)
return 0, err
}
dao.Commit(db)
actID = act.ID
err = SyncAct(ctx, actID, nil, nil, nil)
return actID, err
@@ -211,145 +231,215 @@ func GetActDetail(ctx *jxcontext.Context, actID int) (actDetail *ActDetail, err
return actDetail, err
}
// func GetAcVendorInfo(ctx *jxcontext.Context, actID int) (err error) {
// return err
// }
// func GetAcStoresVendorInfo(ctx *jxcontext.Context, actID int, storeIDs []int) (err error) {
// return err
// }
// func GetAcStoresSkusVendorInfo(ctx *jxcontext.Context, actID int, storeIDs, skuIDs []int) (err error) {
// return err
// }
func parseActStoreSkuParam(actStoreSku []*ActStoreSkuParam) {
}
func UpdateAct(ctx *jxcontext.Context, act *model.Act, actRules []*ActOrderRuleParam, actStoreSku []*ActStoreSkuParam) (err error) {
return err
}
func CancelAct(ctx *jxcontext.Context, actID int) (err error) {
db := dao.GetDB()
act := &model.Act{}
act.ID = actID
if err = dao.GetEntity(db, act); err != nil {
if err = deleteActStoreBind(ctx, db, actID, nil); err != nil {
return err
}
err = SyncAct(ctx, actID, nil, nil, nil)
return err
}
func DeleteActStoreBind(ctx *jxcontext.Context, actID int, actStoreSku []*ActStoreSkuParam) (err error) {
return deleteActStoreBind(ctx, dao.GetDB(), actID, actStoreSku)
}
func deleteActStoreBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, actStoreSkuParam []*ActStoreSkuParam) (err error) {
actMap, err := dao.GetActVendorInfo(db, actID, nil)
if err != nil {
return err
}
actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, nil, nil)
if err != nil {
return err
}
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
if r := recover(); r != nil || err != nil {
dao.Rollback(db)
panic(r)
if r != nil {
panic(r)
}
}
}()
dao.UpdateEntityLogically(db, act, map[string]interface{}{
model.FieldStatus: model.ActStatusCanceled,
}, ctx.GetUserName(), nil)
_, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, &model.ActMap{}, nil, ctx.GetUserName(), map[string]interface{}{
model.FieldActID: actID,
}, model.FieldSyncStatus, model.SyncFlagModifiedMask)
if err == nil {
dao.Commit(db)
globals.SugarLogger.Debugf("CancelAct track:%s", ctx.GetTrackInfo())
err = SyncAct(ctx, actID, nil, nil, nil)
} else {
dao.Rollback(db)
actStoreSkuParamMap := make(map[int64]*ActStoreSkuParam)
for _, v := range actStoreSkuParam {
actStoreSkuParamMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v
if _, err = dao.DeleteEntityLogically(db, &model.ActStoreSku{}, nil, ctx.GetUserName(),
map[string]interface{}{
model.FieldActID: actID,
model.FieldStoreID: v.StoreID,
model.FieldSkuID: v.SkuID,
}); err != nil {
return err
}
}
isNeedCancelAct := true
for vendorID, act := range actMap {
isDeleteAll := true
isDeleteAtLeastOne := false
actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuMap[vendorID])
for storeID := range actStoreSkuMap {
for _, actStoreSku := range actStoreSkuMap[storeID] {
if actStoreSkuParam == nil || actStoreSkuParamMap[jxutils.Combine2Int(actStoreSku.StoreID, actStoreSku.SkuID)] != nil {
if _, err = dao.UpdateEntityLogically(db, partner.ActStoreSku2ActStoreSkuMap(actStoreSku),
map[string]interface{}{
model.FieldSyncStatus: actStoreSku.SyncStatus | model.SyncFlagDeletedMask,
}, ctx.GetUserName(), nil); err != nil {
return err
}
isDeleteAtLeastOne = true
} else {
isNeedCancelAct = false
isDeleteAll = false
}
}
}
if isDeleteAll || isDeleteAtLeastOne {
// globals.SugarLogger.Debugf("isDeleteAll:%t", isDeleteAll)
syncStatus := model.SyncFlagModifiedMask
if isDeleteAll {
syncStatus = model.SyncFlagDeletedMask
}
syncStatus |= act.SyncStatus
if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act),
map[string]interface{}{
model.FieldSyncStatus: syncStatus,
}, ctx.GetUserName(), nil); err != nil {
return err
}
}
if isDeleteAll != isNeedCancelAct {
globals.SugarLogger.Warnf("deleteActStoreBind, actID:%d isDeleteAll:%t != isNeedCancelAct:%t", act.ID, isDeleteAll, isNeedCancelAct)
}
}
if isNeedCancelAct {
act := &model.Act{}
act.ID = actID
if _, err = dao.UpdateEntityLogically(db, act,
map[string]interface{}{
model.FieldStatus: model.ActStatusCanceled,
}, ctx.GetUserName(), nil); err != nil {
return err
}
}
dao.Commit(db)
return err
}
func SyncAct(ctx *jxcontext.Context, actID int, vendorIDs, storeIDs, skuIDs []int) (err error) {
var actOrderRules []*model.ActOrderRule
db := dao.GetDB()
actMap, err := dao.GetActVendorInfo(db, actID, vendorIDs)
if err != nil {
return err
}
actStoreMap, err := dao.GetActStoreVendorInfo(db, actID, vendorIDs, storeIDs)
actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, storeIDs, skuIDs)
if err != nil {
return err
}
actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, vendorIDs, storeIDs, skuIDs)
if err != nil {
return err
}
var realVendorIDs []int
for vendorID := range actMap {
realVendorIDs = append(realVendorIDs, vendorID)
}
task := tasksch.NewParallelTask("SyncAct", nil, ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
vendorID := batchItemList[0].(int)
handler := partner.GetPurchasePlatformFromVendorID(vendorID)
if handler == nil {
err = fmt.Errorf("不被支持的vendorID:%d", vendorID)
} else {
act := actMap[vendorID]
actStore := actStoreMap[vendorID]
actStoreSku := actStoreSkuMap[vendorID]
// globals.SugarLogger.Debugf("%s", utils.Format4Output(act, false))
// globals.SugarLogger.Debugf("%s", utils.Format4Output(actStore, false))
// globals.SugarLogger.Debugf("%s", utils.Format4Output(actStoreSku, false))
if act != nil && actStore != nil && actStoreSku != nil {
if model.IsSyncStatusNeedCreate(act.SyncStatus) {
err = handler.CreateAct(ctx, task, act, actOrderRules, actStore, actStoreSku)
} else if model.IsSyncStatusNeedUpdate(act.SyncStatus) {
if act.Status == model.ActStatusCanceled {
err = handler.CancelAct(ctx, task, act, actStore, actStoreSku)
} else {
// actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update := splitActStore(actStore)
// err = handler.UpdateAct(ctx, task, act, actOrderRules, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update, actStoreSku)
}
}
if err == nil {
actMap := &model.ActMap{}
actMap.ID = act.MapID
dao.UpdateEntityLogically(db, actMap, map[string]interface{}{
model.FieldSyncStatus: 0,
model.FieldVendorActID: act.VendorActID,
}, ctx.GetUserName(), nil)
for _, v := range actStore {
storeMap := model.ActStoreMap{}
storeMap.ID = v.MapID
dao.UpdateEntityLogically(db, storeMap, map[string]interface{}{
model.FieldSyncStatus: 0,
model.FieldVendorActID: v.VendorActID,
}, ctx.GetUserName(), nil)
}
for _, v := range actStoreSku {
storeSkuMap := model.ActStoreSkuMap{}
storeSkuMap.ID = v.MapID
dao.UpdateEntityLogically(db, storeSkuMap, map[string]interface{}{
model.FieldSyncStatus: 0,
model.FieldVendorActID: v.VendorActID,
}, ctx.GetUserName(), nil)
}
}
}
if handler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformActHandler); handler != nil {
if err = handler.SyncAct(ctx, nil, actMap[vendorID], nil, actStoreSkuMap[vendorID]); err != nil {
return err
}
return nil, err
}, realVendorIDs)
tasksch.ManageTask(task).Run()
_, err = task.GetResult(0)
}
}
return err
// var actOrderRules []*model.ActOrderRule
// db := dao.GetDB()
// actMap, err := dao.GetActVendorInfo(db, actID, vendorIDs)
// if err != nil {
// return err
// }
// actStoreMap, err := dao.GetActStoreVendorInfo(db, actID, vendorIDs, storeIDs)
// if err != nil {
// return err
// }
// actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, vendorIDs, storeIDs, skuIDs)
// if err != nil {
// return err
// }
// var realVendorIDs []int
// for vendorID := range actMap {
// realVendorIDs = append(realVendorIDs, vendorID)
// }
// task := tasksch.NewParallelTask("SyncAct", nil, ctx,
// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
// vendorID := batchItemList[0].(int)
// handler := partner.GetPurchasePlatformFromVendorID(vendorID)
// if handler == nil {
// err = fmt.Errorf("不被支持的vendorID:%d", vendorID)
// } else {
// act := actMap[vendorID]
// actStore := actStoreMap[vendorID]
// actStoreSku := actStoreSkuMap[vendorID]
// // globals.SugarLogger.Debugf("%s", utils.Format4Output(act, false))
// // globals.SugarLogger.Debugf("%s", utils.Format4Output(actStore, false))
// // globals.SugarLogger.Debugf("%s", utils.Format4Output(actStoreSku, false))
// if act != nil && actStore != nil && actStoreSku != nil {
// if model.IsSyncStatusNeedCreate(act.SyncStatus) {
// err = handler.CreateAct(ctx, task, act, actOrderRules, actStore, actStoreSku)
// } else if model.IsSyncStatusNeedUpdate(act.SyncStatus) {
// if act.Status == model.ActStatusCanceled {
// err = handler.CancelAct(ctx, task, act, actStore, actStoreSku)
// } else {
// // actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update := splitActStore(actStore)
// // err = handler.UpdateAct(ctx, task, act, actOrderRules, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update, actStoreSku)
// }
// }
// if err == nil {
// actMap := &model.ActMap{}
// actMap.ID = act.MapID
// dao.UpdateEntityLogically(db, actMap, map[string]interface{}{
// model.FieldSyncStatus: 0,
// model.FieldVendorActID: act.VendorActID,
// }, ctx.GetUserName(), nil)
// for _, v := range actStore {
// storeMap := model.ActStoreMap{}
// storeMap.ID = v.MapID
// dao.UpdateEntityLogically(db, storeMap, map[string]interface{}{
// model.FieldSyncStatus: 0,
// model.FieldVendorActID: v.VendorActID,
// }, ctx.GetUserName(), nil)
// }
// for _, v := range actStoreSku {
// storeSkuMap := model.ActStoreSkuMap{}
// storeSkuMap.ID = v.MapID
// dao.UpdateEntityLogically(db, storeSkuMap, map[string]interface{}{
// model.FieldSyncStatus: 0,
// model.FieldVendorActID: v.VendorActID,
// }, ctx.GetUserName(), nil)
// }
// }
// }
// }
// return nil, err
// }, realVendorIDs)
// tasksch.ManageTask(task).Run()
// _, err = task.GetResult(0)
return err
}
func splitActStore(actStore []*model.ActStore2) (actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2) {
for _, v := range actStore {
if model.IsSyncStatusNeedDelete(v.SyncStatus) {
if !dao.IsVendorThingIDEmpty(v.VendorActID) {
actStoreMap2Remove = append(actStoreMap2Remove, v)
}
} else if model.IsSyncStatusNeedCreate(v.SyncStatus) {
actStoreMap2Add = append(actStoreMap2Add, v)
} else if model.IsSyncStatusNeedUpdate(v.SyncStatus) {
actStoreMap2Update = append(actStoreMap2Update, v)
}
}
return actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update
}
// func splitActStore(actStore []*model.ActStore2) (actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2) {
// for _, v := range actStore {
// if model.IsSyncStatusNeedDelete(v.SyncStatus) {
// if !dao.IsVendorThingIDEmpty(v.VendorActID) {
// actStoreMap2Remove = append(actStoreMap2Remove, v)
// }
// } else if model.IsSyncStatusNeedCreate(v.SyncStatus) {
// actStoreMap2Add = append(actStoreMap2Add, v)
// } else if model.IsSyncStatusNeedUpdate(v.SyncStatus) {
// actStoreMap2Update = append(actStoreMap2Update, v)
// }
// }
// return actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update
// }

View File

@@ -21,30 +21,38 @@ func init() {
func TestInitDb(t *testing.T) {
dao.ExecuteSQL(dao.GetDB(), `
DROP TABLE IF EXISTS act,act_map, act_order_rule, act_store_map, act_store_sku, act_store_sku_map;
DROP TABLE IF EXISTS act, act_map, act_order_rule, act_store_sku, act_store_sku_map;
`)
}
func TestCreateAct(t *testing.T) {
actID, err := CreateAct(jxcontext.AdminCtx, &model.Act{
Name: "测试活动2",
Name: "测试活动",
PricePercentage: 80,
}, []int{0, 1, 3}, nil, []*ActStoreSkuParam{
}, []int{0}, nil, []*ActStoreSkuParam{
&ActStoreSkuParam{
StoreID: 100119,
SkuID: 30828,
ActStoreSku: model.ActStoreSku{
StoreID: 100119,
SkuID: 30828,
},
},
&ActStoreSkuParam{
StoreID: 100119,
SkuID: 30827,
ActStoreSku: model.ActStoreSku{
StoreID: 100119,
SkuID: 30827,
},
},
&ActStoreSkuParam{
StoreID: 100118,
SkuID: 30592,
ActStoreSku: model.ActStoreSku{
StoreID: 100118,
SkuID: 30592,
},
},
&ActStoreSkuParam{
StoreID: 100118,
SkuID: 30565,
ActStoreSku: model.ActStoreSku{
StoreID: 100118,
SkuID: 30565,
},
},
})
if err != nil {
@@ -60,6 +68,70 @@ func TestCancelAct(t *testing.T) {
}
}
func TestDeleteActStoreBind(t *testing.T) {
err := DeleteActStoreBind(jxcontext.AdminCtx, 1, []*ActStoreSkuParam{
// &ActStoreSkuParam{
// ActStoreSku: model.ActStoreSku{
// StoreID: 100119,
// SkuID: 30828,
// },
// },
// &ActStoreSkuParam{
// ActStoreSku: model.ActStoreSku{
// StoreID: 100119,
// SkuID: 30827,
// },
// },
&ActStoreSkuParam{
ActStoreSku: model.ActStoreSku{
StoreID: 100118,
SkuID: 30592,
},
},
&ActStoreSkuParam{
ActStoreSku: model.ActStoreSku{
StoreID: 100118,
SkuID: 30565,
},
},
})
if err != nil {
t.Fatal(err)
}
}
func TestAddActStoreBind(t *testing.T) {
err := AddActStoreBind(jxcontext.AdminCtx, 1, []*ActStoreSkuParam{
// &ActStoreSkuParam{
// ActStoreSku: model.ActStoreSku{
// StoreID: 100119,
// SkuID: 30828,
// },
// },
// &ActStoreSkuParam{
// ActStoreSku: model.ActStoreSku{
// StoreID: 100119,
// SkuID: 30827,
// },
// },
&ActStoreSkuParam{
ActStoreSku: model.ActStoreSku{
StoreID: 100118,
SkuID: 30592,
},
},
&ActStoreSkuParam{
ActStoreSku: model.ActStoreSku{
StoreID: 100118,
SkuID: 30565,
},
},
})
if err != nil {
t.Fatal(err)
}
}
func TestSyncAct(t *testing.T) {
err := SyncAct(jxcontext.AdminCtx, 1, nil, nil, nil)
if err != nil {

View File

@@ -45,6 +45,8 @@ type StoreSkuNameExt struct {
PendingOpType int8 `json:"pendingOpType"` // 取值同 StoreOpRequest.Type
PendingUnitPrice int `json:"pendingUnitPrice"` // 这个是待审核的价格申请
PayPercentage int `json:"-"`
}
// GetStoreSkus用
@@ -98,28 +100,55 @@ type StoreOpRequestInfo struct {
UnitPrice int `json:"unitPrice"`
}
// 待用于新的GetStoresSkus实现
type tSkuInfo struct {
ID int `orm:"column(sku_id)" json:"id"`
CreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"`
UpdatedAt time.Time `orm:"auto_now;type(datetime)" json:"updatedAt"`
LastOperator string `orm:"size(32)" json:"lastOperator"` // 最后操作员
DeletedAt time.Time `orm:"type(datetime);default('1970-01-01 00:00:00')" json:"deletedAt"`
CategoryID int `orm:"column(category_id)" json:"categoryID"` // 特殊类别,一般用于秒杀,特价之类的特殊类别
NameID int `orm:"column(name_id)" json:"nameID"` // todo 这个索引应该要求唯一
SkuIndex int `json:"-"`
Comment string `orm:"size(255)" json:"comment"`
SpecQuality float32 `json:"specQuality"`
SpecUnit string `orm:"size(8)" json:"specUnit"` // 质量或容量
Weight int `json:"weight"` // 重量/质量单位为克当相应的SkuName的SpecUnit为g或kg时必须等于SpecQuality
Status int `json:"status"`
JdID int64 `orm:"column(jd_id);null;index" json:"jdID"`
EbaiID int64 `orm:"column(ebai_id);index"`
MtwmID string `orm:"column(mtwm_id);index;size(16)"` // 美团外卖没有ID保存名字
JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"`
EbaiSyncStatus int8 `orm:"default(2)"`
MtwmSyncStatus int8 `orm:"default(2)"`
}
const (
maxStoreNameBind = 3000 // 最大门店SkuName bind个数
maxStoreNameBind2 = 10000 // 最大门店乘SkuName个数
)
func GetStoreSkus(ctx *jxcontext.Context, storeID int, isFocus bool, keyword string, isBySku bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *StoreSkuNamesInfo, err error) {
return GetStoresSkus(ctx, []int{storeID}, isFocus, keyword, isBySku, params, offset, pageSize)
func GetStoreSkus(ctx *jxcontext.Context, storeID int, skuIDs []int, isFocus bool, keyword string, isBySku bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *StoreSkuNamesInfo, err error) {
return GetStoresSkus(ctx, []int{storeID}, skuIDs, isFocus, keyword, isBySku, params, offset, pageSize)
}
// 商品不可售,直接排除
// 如果门店商品是可售状态,那么会忽略区域限制。否则有区域限制
func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword string, isBySku bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *StoreSkuNamesInfo, err error) {
db := dao.GetDB()
sql := `
func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool, keyword string, isBySku bool, params map[string]interface{}) (sql string, sqlParams []interface{}, err error) {
sql = `
FROM sku_name t1
JOIN sku t2 ON t1.id = t2.name_id AND t2.deleted_at = ?/* AND t2.status = ?*/
JOIN store t3 ON t3.id IN (` + dao.GenQuestionMarks(len(storeIDs)) + `)
LEFT JOIN store_sku_bind t4 ON t4.sku_id = t2.id AND t4.deleted_at = ? AND t4.store_id = t3.id
JOIN store t3 ON t3.id IN (` + dao.GenQuestionMarks(len(storeIDs)) + `)`
if !isFocus {
sql += " LEFT"
}
sql += `
JOIN store_sku_bind t4 ON t4.sku_id = t2.id AND t4.deleted_at = ? AND t4.store_id = t3.id
LEFT JOIN sku_name_place_bind t5 ON t1.id = t5.name_id AND t3.city_code = t5.place_code
WHERE t1.deleted_at = ? AND (t1.is_global = 1 OR t5.id IS NOT NULL OR 1 = ?)/* AND t1.status = ?*/
`
sqlParams := []interface{}{
sqlParams = []interface{}{
utils.DefaultTimeValue,
// model.SkuStatusNormal,
storeIDs,
@@ -129,10 +158,10 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
// model.SkuStatusNormal,
}
if isFocus {
sql += " AND t4.sku_id IS NOT NULL AND ((t2.status = ? AND t1.status = ?) OR t4.status = ?)"
sql += " AND ((t2.status = ? AND t1.status = ?) OR t4.status = ?)"
sqlParams = append(sqlParams, model.SkuStatusNormal, model.SkuStatusNormal, model.SkuStatusNormal)
} else {
sql += " AND t4.sku_id IS NULL AND t2.status = ? AND t1.status = ?"
sql += " AND t4.sku_id IS NULL AND (t2.status = ? AND t1.status = ?)"
sqlParams = append(sqlParams, model.SkuStatusNormal, model.SkuStatusNormal)
}
if keyword != "" {
@@ -141,8 +170,12 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike)
if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil {
sql += " OR t1.id = ? OR t2.id = ? OR t2.jd_id = ? OR t4.ebai_id = ? OR t4.mtwm_id = ?"
sqlParams = append(sqlParams, keywordInt64, keywordInt64, keywordInt64, keywordInt64, keywordInt64)
sql += " OR t1.id = ? OR t2.id = ? OR t2.jd_id = ?"
sqlParams = append(sqlParams, keywordInt64, keywordInt64, keywordInt64)
if isFocus {
sql += " OR t4.ebai_id = ? OR t4.mtwm_id = ?"
sqlParams = append(sqlParams, keywordInt64, keywordInt64)
}
}
sql += ")"
}
@@ -154,7 +187,7 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
if params["nameIDs"] != nil {
var nameIDs []int
if err = utils.UnmarshalUseNumber([]byte(params["nameIDs"].(string)), &nameIDs); err != nil {
return nil, err
return "", nil, err
}
if len(nameIDs) > 0 {
sql += " AND t1.id IN (" + dao.GenQuestionMarks(len(nameIDs)) + ")"
@@ -165,7 +198,7 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
cat := &model.SkuCategory{}
cat.ID = params["categoryID"].(int)
if err = dao.GetEntity(db, cat); err != nil {
return nil, err
return "", nil, err
}
sql += " AND (t1.category_id = ?"
sqlParams = append(sqlParams, cat.ID)
@@ -191,25 +224,15 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
sql += " AND t1.unit = ?"
sqlParams = append(sqlParams, params["unit"].(string))
}
if params["skuID"] != nil {
if len(skuIDs) > 0 {
sql += " AND t2.id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")"
sqlParams = append(sqlParams, skuIDs)
} else if params["skuID"] != nil {
skuID, ok := params["skuID"].(int)
if ok {
skuIDs = append(skuIDs, skuID)
sql += " AND t2.id = ?"
sqlParams = append(sqlParams, skuID)
} else { // todo 这里是没有用的,应该删除掉
skuIDs := params["skuID"].([]interface{})
sql += " AND t2.id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")"
sqlParams = append(sqlParams, skuIDs)
}
}
if params["skuIDs"] != nil {
var skuIDs []int
if err = utils.UnmarshalUseNumber([]byte(params["skuIDs"].(string)), &skuIDs); err != nil {
return nil, err
}
if len(skuIDs) > 0 {
sql += " AND t2.id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")"
sqlParams = append(sqlParams, skuIDs)
}
}
if isFocus {
@@ -225,7 +248,7 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
if params["jdSyncStatus"] != nil || params["ebaiSyncStatus"] != nil || params["mtwmSyncStatus"] != nil {
realVendorMap, err2 := getValidStoreVendorMap(db, storeIDs)
if err = err2; err != nil {
return nil, err
return "", nil, err
}
sql += " AND ( 1 = 0"
if params["jdSyncStatus"] != nil && realVendorMap[model.VendorIDJD] == 1 {
@@ -243,6 +266,17 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
sql += ")"
}
}
return sql, sqlParams, err
}
// 商品不可售,直接排除
// 如果门店商品是可售状态,那么会忽略区域限制。否则有区域限制
func GetStoresSkus(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus bool, keyword string, isBySku bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *StoreSkuNamesInfo, err error) {
db := dao.GetDB()
sql, sqlParams, err := getGetStoresSkusBaseSQL(db, storeIDs, skuIDs, isFocus, keyword, isBySku, params)
if err != nil {
return nil, err
}
sql += `
GROUP BY
t1.id,
@@ -260,7 +294,8 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
t1.img,
t1.elm_img_hash_code,
t3.id,
t3.name`
t3.name,
t3.pay_percentage`
if isBySku {
sql += `,
t2.id`
@@ -284,6 +319,7 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
t1.elm_img_hash_code,
t3.id store_id,
t3.name store_name,
t3.pay_percentage,
CONCAT("[", GROUP_CONCAT(DISTINCT CONCAT('{"id":', t2.id, ',"comment":"', t2.comment, '","status":', t2.status, ',"createdAt":"',
CONCAT(REPLACE(IF(t4.created_at IS NULL, '1970-01-01 00:00:00', t4.created_at)," ","T"),"+08:00"), '","updatedAt":"', CONCAT(REPLACE(IF(t4.updated_at IS NULL, '1970-01-01 00:00:00', t4.updated_at)," ","T"),"+08:00"),
'","lastOperator":"', IF(t4.last_operator IS NULL, '', t4.last_operator), '","specQuality":', t2.spec_quality, ',"specUnit":"', t2.spec_unit, '","weight":', t2.weight,
@@ -319,6 +355,20 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
// globals.SugarLogger.Debug(sqlData, sqlParams)
if err = dao.GetRows(db, &skuNamesInfo.SkuNames, sqlData, sqlParams...); err == nil {
skuNamesInfo.TotalCount = dao.GetLastTotalRowCount(db)
// 活动商品信息
jxSkuPriceMap, err2 := dao.GetPromotionSkuPriceMap(db, model.VendorIDJX, storeIDs, skuIDs, time.Now(), time.Now())
if err = err2; err != nil {
dao.Rollback(db)
globals.SugarLogger.Errorf("GetStoresSkus can not get sku promotion info for error:%v", err)
return nil, err
}
jdSkuPriceMap, err2 := dao.GetPromotionSkuPriceMap(db, model.VendorIDJD, storeIDs, skuIDs, time.Now(), time.Now())
if err = err2; err != nil {
dao.Rollback(db)
globals.SugarLogger.Errorf("GetStoresSkus can not get sku promotion info for error:%v", err)
return nil, err
}
for _, skuName := range skuNamesInfo.SkuNames {
if skuName.SkusStr != "" {
if err = utils.UnmarshalUseNumber([]byte(skuName.SkusStr), &skuName.Skus); err != nil {
@@ -328,6 +378,26 @@ func GetStoresSkus(ctx *jxcontext.Context, storeIDs []int, isFocus bool, keyword
if len(skuName.Skus) > 0 {
skuName.UnitPrice = int(utils.MustInterface2Int64(skuName.Skus[0]["unitPrice"]))
for _, v := range skuName.Skus {
index := dao.GenSkuPriceMapKey(skuName.StoreID, int(utils.MustInterface2Int64(v["id"])))
if jdSkuPriceMap[index] != nil {
v["actPrice"] = jdSkuPriceMap[index].Price
} else {
v["actPrice"] = 0
}
earningPrice := 0
if jxSkuPriceMap[index] != nil {
earningPrice = jxSkuPriceMap[index].EarningPrice
}
v["earningPrice"] = earningPrice
realEarningPrice := earningPrice
if realEarningPrice == 0 {
shopPrice := utils.Interface2Int64WithDefault(v["price"], 0)
realEarningPrice = int(jxutils.CaculateSkuEarningPrice(shopPrice, shopPrice, skuName.PayPercentage))
}
v["realEarningPrice"] = realEarningPrice
delete(v, "unitPrice")
}
} else {
@@ -897,6 +967,13 @@ func updateStoreSkusSaleWithoutSync(ctx *jxcontext.Context, storeID int, skuBind
var num int64
db := dao.GetDB()
needSyncIDMap := make(map[int]int)
skuIDMap := make(map[int]int)
skuBindSkuInfosMap := make(map[int]*StoreSkuBindSkuInfo)
for _, v := range skuBindSkuInfos {
skuIDMap[v.SkuID] = 1
skuBindSkuInfosMap[v.SkuID] = v
}
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
@@ -904,9 +981,13 @@ func updateStoreSkusSaleWithoutSync(ctx *jxcontext.Context, storeID int, skuBind
panic(r)
}
}()
for _, v := range skuBindSkuInfos {
if v.IsSale != 0 {
skuBind := &model.StoreSkuBind{}
storeSkuList, err := dao.GetStoresSkusInfo(db, []int{storeID}, jxutils.IntMap2List(skuIDMap))
if err != nil {
dao.Rollback(db)
return nil, err
}
for _, skuBind := range storeSkuList {
if v := skuBindSkuInfosMap[skuBind.SkuID]; v != nil && v.IsSale != 0 {
if v.IsSale == 1 {
skuBind.Status = model.StoreSkuBindStatusNormal
} else {
@@ -919,10 +1000,7 @@ func updateStoreSkusSaleWithoutSync(ctx *jxcontext.Context, storeID int, skuBind
model.FieldMtwmSyncStatus: skuBind.MtwmSyncStatus | model.SyncFlagSaleMask,
model.FieldElmSyncStatus: skuBind.ElmSyncStatus | model.SyncFlagSaleMask,
model.FieldWscSyncStatus: skuBind.WscSyncStatus | model.SyncFlagSaleMask,
}, userName, map[string]interface{}{
model.FieldStoreID: storeID,
model.FieldSkuID: v.SkuID,
}); err != nil {
}, userName, nil); err != nil {
dao.Rollback(db)
return nil, err
}

View File

@@ -400,7 +400,7 @@ func (v *VendorSync) SyncStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, vendo
loopMapInfo := batchItemList[0].(*LoopStoreMapInfo)
if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil {
if isForce {
dao.SetStoreSkuSyncStatus(db, loopMapInfo.VendorID, storeIDs, skuIDs, model.SyncFlagModifiedMask)
dao.SetStoreSkuSyncStatus(db, loopMapInfo.VendorID, storeIDs, skuIDs, model.SyncFlagStoreSkuModifiedMask)
}
if len(loopMapInfo.StoreMapList) > 1 {
var loopStoreTask tasksch.ITask

View File

@@ -79,6 +79,49 @@ func RefreshRealMobile(ctx *jxcontext.Context, vendorID int, fromTime, toTime ti
return hint, err
}
func RefreshOrderFinancial(ctx *jxcontext.Context, fromTime, toTime time.Time, isAsync, isContinueWhenError bool) (hint string, err error) {
sql := `
SELECT *
FROM goods_order
WHERE status = ? AND total_shop_money = 0
`
sqlParams := []interface{}{
model.OrderStatusFinished,
}
if !utils.IsTimeZero(fromTime) {
sql += " AND order_created_at >= ?"
sqlParams = append(sqlParams, fromTime)
}
if !utils.IsTimeZero(toTime) {
sql += " AND order_created_at <= ?"
sqlParams = append(sqlParams, toTime)
}
var orderList []*model.GoodsOrder
db := dao.GetDB()
if err = dao.GetRows(db, &orderList, sql, sqlParams...); err == nil && len(orderList) > 0 {
task := tasksch.NewParallelTask("misc RefreshOrderFinancial", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
order := batchItemList[0].(*model.GoodsOrder)
handler := partner.GetPurchasePlatformFromVendorID(order.VendorID)
if handler != nil {
remoteOrder, err2 := handler.GetOrder(order.VendorOrderID)
if err = err2; err == nil {
order.TotalShopMoney = remoteOrder.TotalShopMoney
order.PmSubsidyMoney = remoteOrder.PmSubsidyMoney
err = partner.CurOrderManager.UpdateOrderFields(order, []string{"TotalShopMoney", "PmSubsidyMoney"})
}
}
return nil, err
}, orderList)
tasksch.HandleTask(task, nil, true).Run()
hint = task.ID
if !isAsync {
_, err = task.GetResult(0)
}
}
return hint, err
}
func StartDailyWork() {
if globals.ReallyCallPlatformAPI {
now := time.Now()

View File

@@ -283,82 +283,96 @@ func CreateJdPromotion(ctx *jxcontext.Context, vendorID int, isIDJd bool, isAsyn
Source: PromotionSourceOpenPlatform,
}
if vendorPromotionID == "" && vendorID == model.VendorIDJD {
skuIDs := make([]int, len(params.SkuPrices))
skuPriceMap := make(map[int64]*SkuPrice)
for k, v := range params.SkuPrices {
skuIDs[k] = v.SkuID
skuPriceMap[int64(v.SkuID)] = v
skuIDs := make([]int, len(params.SkuPrices))
skuPriceMap := make(map[int64]*SkuPrice)
for k, v := range params.SkuPrices {
skuIDs[k] = v.SkuID
skuPriceMap[int64(v.SkuID)] = v
}
if len(skuIDs) == 0 {
return "", fmt.Errorf("商品列表为空")
}
if vendorID == model.VendorIDJX {
conflictPromotion, err2 := dao.GetPromotionSkuPriceMap(db, model.VendorIDJX, params.StoreIDs, skuIDs, promotion.BeginAt, promotion.EndAt)
if err = err2; err != nil {
return "", err
}
sql := `
if len(conflictPromotion) > 0 {
return "", fmt.Errorf("有冲突配置:%s", utils.Format4Output(conflictPromotion, false))
}
}
if vendorPromotionID == "" {
if vendorID == model.VendorIDJD {
sql := `
SELECT t1.*, t2.jd_id, t3.vendor_store_id
FROM store_sku_bind t1
JOIN sku t2 ON t1.sku_id = t2.id
JOIN store_map t3 ON t1.store_id = t3.store_id AND t3.vendor_id = ? AND t3.deleted_at = ?
WHERE t1.deleted_at = ?
`
sqlParam := []interface{}{
model.VendorIDJD,
utils.DefaultTimeValue,
utils.DefaultTimeValue,
skuIDs,
}
if isIDJd {
sql += " AND t2.jd_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ") AND t3.vendor_store_id = ?"
} else {
sql += " AND t1.sku_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ") AND t1.store_id = ?"
}
sqlParam := []interface{}{
model.VendorIDJD,
utils.DefaultTimeValue,
utils.DefaultTimeValue,
skuIDs,
}
if isIDJd {
sql += " AND t2.jd_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ") AND t3.vendor_store_id = ?"
} else {
sql += " AND t1.sku_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ") AND t1.store_id = ?"
}
errMsg := ""
index := 0
for _, storeID := range params.StoreIDs {
var skuBinds []*tStoreSkuBindExt
if err = dao.GetRows(db, &skuBinds, sql, append(sqlParam, storeID)...); err != nil {
return "", err
}
for k, skuBind := range skuBinds {
if k == 0 {
jxStoreIDs = append(jxStoreIDs, skuBind.StoreID)
errMsg := ""
index := 0
for _, storeID := range params.StoreIDs {
var skuBinds []*tStoreSkuBindExt
if err = dao.GetRows(db, &skuBinds, sql, append(sqlParam, storeID)...); err != nil {
return "", err
}
mapSkuID := int64(skuBind.SkuID)
if isIDJd {
mapSkuID = skuBind.JdSkuID
}
promotionSkuPrice := skuPriceMap[mapSkuID]
if promotionSkuPrice.PriceType == PriceTypePercentage {
promotionSkuPrice.Price = skuBind.Price * promotionSkuPrice.Price / 100
}
if vendorID != model.VendorIDJX && promotionSkuPrice.Price >= skuBind.Price {
errMsg += fmt.Sprintf("活动价大于等于原价storeID:%d, skuID:%d\n", skuBind.StoreID, skuBind.SkuID)
}
if promotionSkuPrice.LimitSkuCount <= 0 {
promotionSkuPrice.LimitSkuCount = DefaultLimitSkuCount
}
if errMsg == "" {
if params.Type == PromotionTypeLimitedTime {
if skuBind.Price*PromotionLimitedTimeMinPercentage/100 < promotionSkuPrice.Price {
modifyPricesList[skuBind.StoreID] = append(modifyPricesList[skuBind.StoreID], &jdapi.SkuPriceInfo{
OutSkuId: utils.Int2Str(skuBind.SkuID),
Price: promotionSkuPrice.Price*100/PromotionLimitedTimeMinPercentage + 5,
})
for k, skuBind := range skuBinds {
if k == 0 {
jxStoreIDs = append(jxStoreIDs, skuBind.StoreID)
}
mapSkuID := int64(skuBind.SkuID)
if isIDJd {
mapSkuID = skuBind.JdSkuID
}
promotionSkuPrice := skuPriceMap[mapSkuID]
if promotionSkuPrice.PriceType == PriceTypePercentage {
promotionSkuPrice.Price = skuBind.Price * promotionSkuPrice.Price / 100
}
if vendorID != model.VendorIDJX && promotionSkuPrice.Price >= skuBind.Price {
errMsg += fmt.Sprintf("活动价大于等于原价storeID:%d, skuID:%d\n", skuBind.StoreID, skuBind.SkuID)
}
if promotionSkuPrice.LimitSkuCount <= 0 {
promotionSkuPrice.LimitSkuCount = DefaultLimitSkuCount
}
if errMsg == "" {
if params.Type == PromotionTypeLimitedTime {
if skuBind.Price*PromotionLimitedTimeMinPercentage/100 < promotionSkuPrice.Price {
modifyPricesList[skuBind.StoreID] = append(modifyPricesList[skuBind.StoreID], &jdapi.SkuPriceInfo{
OutSkuId: utils.Int2Str(skuBind.SkuID),
Price: promotionSkuPrice.Price*100/PromotionLimitedTimeMinPercentage + 5,
})
}
}
promotionPrices[index] = &jdapi.PromotionSku{
StationNo: utils.Str2Int64(skuBind.VendorStoreID),
SkuID: skuBind.JdSkuID,
PromotionPrice: int64(promotionSkuPrice.Price),
LimitSkuCount: promotionSkuPrice.LimitSkuCount,
}
index++
}
promotionPrices[index] = &jdapi.PromotionSku{
StationNo: utils.Str2Int64(skuBind.VendorStoreID),
SkuID: skuBind.JdSkuID,
PromotionPrice: int64(promotionSkuPrice.Price),
LimitSkuCount: promotionSkuPrice.LimitSkuCount,
}
index++
}
}
}
if errMsg != "" {
return "", errors.New(errMsg)
}
promotionPrices = promotionPrices[:index]
if len(promotionPrices) == 0 {
return "", ErrEmptySkus
if errMsg != "" {
return "", errors.New(errMsg)
}
promotionPrices = promotionPrices[:index]
if len(promotionPrices) == 0 {
return "", ErrEmptySkus
}
}
} else {
promotion.VendorPromotionID = vendorPromotionID
@@ -653,20 +667,25 @@ func CancelJdPromotion(ctx *jxcontext.Context, promotionID int) (err error) {
if err = dao.GetEntity(db, promotion); err != nil {
return err
}
if promotion.Status != model.PromotionStatusRemoteCreated {
return errors.New("当前状态不能进行取消操作")
if promotion.Status == model.PromotionStatusCanceled {
return errors.New("当前状态已经是取消")
}
promotionHandler := getPromotionHander(promotion.Type)
if promotionHandler == nil {
return errors.New("非法的活动类型")
}
if err = promotionHandler.CancelPromotion(utils.Str2Int64(promotion.VendorPromotionID), ""); err == nil {
if _, err = dao.UpdateEntityLogically(db, promotion, map[string]interface{}{
"Status": model.PromotionStatusCanceled,
}, ctx.GetUserName(), nil); err == nil {
RefreshJdPromotionLockStatus(ctx, promotionID)
if promotion.Status == model.PromotionStatusRemoteCreated {
if promotion.VendorPromotionID != "" {
promotionHandler := getPromotionHander(promotion.Type)
if promotionHandler == nil {
return errors.New("非法的活动类型")
}
if err = promotionHandler.CancelPromotion(utils.Str2Int64(promotion.VendorPromotionID), ""); err != nil {
return err
}
}
}
if _, err = dao.UpdateEntityLogically(db, promotion, map[string]interface{}{
"Status": model.PromotionStatusCanceled,
}, ctx.GetUserName(), nil); err == nil {
// RefreshJdPromotionLockStatus(ctx, promotionID)
}
return err
}

View File

@@ -374,3 +374,15 @@ func GuessVendorIDFromVendorStoreID(vendorStoreID int64) (vendorID int) {
func GetVendorName(vendorID int) (vendorName string) {
return model.VendorChineseNames[vendorID]
}
func CaculateSkuEarningPrice(shopPrice, salePrice int64, storePayPercentage int) (earningPrice int64) {
earningPrice = salePrice
if shopPrice > 0 && shopPrice < earningPrice {
earningPrice = shopPrice
}
if storePayPercentage <= 0 {
storePayPercentage = model.DefaultEarningPricePercentage
}
earningPrice = earningPrice * int64(storePayPercentage) / 100
return earningPrice
}

View File

@@ -3,6 +3,7 @@ package model
import "time"
const (
ActSkuFake = 0 // 假活动,只用于存储活动结算信息
ActSkuDirectDown = 1
ActSkuSecKill = 2
@@ -47,6 +48,13 @@ type ActMap struct {
SyncStatus int `orm:"default(2)" json:"syncStatus"`
}
func (*ActMap) TableUnique() [][]string {
return [][]string{
[]string{"ActID", "VendorID", "DeletedAt"},
}
}
// 不建表
type Act2 struct {
MapID int `orm:"column(map_id)"`
@@ -65,32 +73,6 @@ type ActOrderRule struct {
DeductPrice int64 `orm:"" json:"deductPrice"` // 减的价格
}
// type ActStore struct {
// ModelIDCULD
// ActID int `orm:"column(act_id)" json:"actID"`
// StoreID int `orm:"column(store_id)" json:"storeID"`
// }
type ActStoreMap struct {
ModelIDCULD
ActID int `orm:"column(act_id)" json:"actID"`
StoreID int `orm:"column(store_id)" json:"storeID"`
VendorID int `orm:"column(vendor_id)" json:"vendorID"`
VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"`
SyncStatus int `orm:"default(2)" json:"syncStatus"`
}
type ActStore2 struct {
MapID int `orm:"column(map_id)"`
ActStoreMap
VendorStoreID string `orm:"column(vendor_store_id)" json:"vendorStoreID"`
}
type ActStoreSku struct {
ModelIDCULD
@@ -103,13 +85,21 @@ type ActStoreSku struct {
OriginalPrice int64 `orm:"" json:"originalPrice"` // 单品级活动用,创建活动时商品的原始京西价
PricePercentage int `orm:"" json:"pricePercentage"` // 单品级活动用SKU级的价格比例非0覆盖Act中的PricePercentage
ActPrice int64 `orm:"" json:"actPrice"` // 单品级活动用SKU级指定的价格非0覆盖CustomPricePercentage与Act中的PricePercentage
EarningPrice int64 `json:"earningPrice"` // 活动商品设置,结算给门店老板的钱
Stock int `orm:"" json:"stock"` // 订单级活动用
}
func (*ActStoreSku) TableUnique() [][]string {
return [][]string{
[]string{"ActID", "StoreID", "SkuID", "DeletedAt"},
}
}
type ActStoreSkuMap struct {
ModelIDCULD
BindID int `orm:"column(bind_id)" json:"bindID"`
ActID int `orm:"column(act_id)" json:"actID"`
StoreID int `orm:"column(store_id)" json:"storeID"`
SkuID int `orm:"column(sku_id)" json:"skuID"`
@@ -120,6 +110,19 @@ type ActStoreSkuMap struct {
ActualActPrice int64 `orm:"" json:"actualActPrice"` // 单品级活动用,创建活动时商品的活动价格
}
func (*ActStoreSkuMap) TableUnique() [][]string {
return [][]string{
[]string{"ActID", "BindID", "VendorID"},
}
}
func (*ActStoreSkuMap) TableIndex() [][]string {
return [][]string{
[]string{"ActID", "StoreID", "SkuID", "VendorID", "DeletedAt"},
}
}
// 不建表
type ActStoreSku2 struct {
MapID int `orm:"column(map_id)"`

View File

@@ -26,17 +26,19 @@ type GoodsOrderExt struct {
WaybillCreatedAt time.Time `orm:"type(datetime);index" json:"waybillCreatedAt"`
WaybillFinishedAt time.Time `orm:"type(datetime)" json:"waybillFinishedAt"`
SkuID int `orm:"column(sku_id)" json:"skuID,omitempty"`
SkuShopPrice int `json:"skuShopPrice,omitempty"`
SkuSalePrice int `json:"skuSalePrice,omitempty"`
SkuCount2 int `json:"skuCount2,omitempty"`
SkuInfo string `json:"skuInfo,omitempty"`
SkuID int `orm:"column(sku_id)" json:"skuID,omitempty"`
SkuShopPrice int `json:"skuShopPrice,omitempty"`
SkuSalePrice int `json:"skuSalePrice,omitempty"`
SkuEarningPrice int `json:"skuEarningPrice,omitempty"`
SkuCount2 int `json:"skuCount2,omitempty"`
SkuInfo string `json:"skuInfo,omitempty"`
}
type OrderSkuExt struct {
OrderSku
FullSkuName string `json:"fullSkuName"`
Image string `json:"image"`
FullSkuName string `json:"fullSkuName"`
Image string `json:"image"`
RealEarningPrice int64 `json:"realEarningPrice"` // 实际单品结算给门店老板钱
}
type GoodsOrderCountInfo struct {

View File

@@ -406,3 +406,7 @@ func WaybillVendorID2Mask(vendorID int) (mask int8) {
func IsAfsOrderFinalStatus(status int) bool {
return status >= AfsOrderStatusFinished && status <= AfsOrderStatusFailed
}
const (
DefaultEarningPricePercentage = 70 // 门店缺省结算百分比
)

View File

@@ -32,38 +32,6 @@ func GetActVendorInfo(db *DaoDB, actID int, vendorIDs []int) (actMap map[int]*mo
return actMap, err
}
func GetActStoreVendorInfo(db *DaoDB, actID int, vendorIDs, storeIDs []int) (actStoreMap map[int][]*model.ActStore2, err error) {
sql := `
SELECT t1.*,
t1.id map_id,
t2.vendor_store_id
FROM act_store_map t1
JOIN store_map t2 ON t2.store_id = t1.store_id AND t2.vendor_id = t1.vendor_id AND t2.deleted_at = ?
WHERE t1.deleted_at = ? AND t1.act_id = ?
`
sqlParams := []interface{}{
utils.DefaultTimeValue,
utils.DefaultTimeValue,
actID,
}
if len(vendorIDs) > 0 {
sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
sqlParams = append(sqlParams, vendorIDs)
}
if len(storeIDs) > 0 {
sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
sqlParams = append(sqlParams, storeIDs)
}
var actStoreList []*model.ActStore2
if err = GetRows(db, &actStoreList, sql, sqlParams...); err == nil {
actStoreMap = make(map[int][]*model.ActStore2)
for _, v := range actStoreList {
actStoreMap[v.VendorID] = append(actStoreMap[v.VendorID], v)
}
}
return actStoreMap, err
}
func GetActStoreSkuVendorInfo(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs []int) (actStoreSkuMap map[int][]*model.ActStoreSku2, err error) {
sql := `
SELECT t1.*,
@@ -79,15 +47,14 @@ func GetActStoreSkuVendorInfo(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs
ELSE
''
END vendor_sku_id
FROM act_store_sku t1
JOIN act_store_sku_map t2 ON t2.act_id = t1.act_id AND t2.sku_id = t1.sku_id AND t2.store_id = t1.store_id AND t2.deleted_at = ?
FROM act_store_sku_map t2
JOIN act_store_sku t1 ON t1.id = t2.bind_id
JOIN store_map t3 ON t3.store_id = t1.store_id AND t3.vendor_id = t2.vendor_id AND t3.deleted_at = ?
JOIN sku t4 ON t4.id = t1.sku_id AND t4.deleted_at = ?
JOIN store_sku_bind t5 ON t5.sku_id = t1.sku_id AND t5.store_id = t1.store_id AND t5.deleted_at = ?
WHERE t1.deleted_at = ? AND t1.act_id = ?
WHERE t2.deleted_at = ? AND t2.act_id = ?
`
sqlParams := []interface{}{
utils.DefaultTimeValue,
utils.DefaultTimeValue,
utils.DefaultTimeValue,
utils.DefaultTimeValue,

View File

@@ -11,6 +11,11 @@ import (
"github.com/astaxie/beego/orm"
)
type KVUpdateItem struct {
Item interface{}
KVs map[string]interface{}
}
// 这里面的函数要求实体是IDCUDL的即含有ID, UpdatedAt, LastOperator, DeletedAt字段
func GetEntitiesByKV(db *DaoDB, item interface{}, conditions map[string]interface{}, isIncludeDeleted bool) (err error) {
@@ -57,6 +62,29 @@ func UpdateEntityByKV(db *DaoDB, item interface{}, kvs map[string]interface{}, c
return num, err
}
func BatchUpdateEntityByKV(db *DaoDB, items []*KVUpdateItem) (num int64, err error) {
if len(items) > 0 {
Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
Rollback(db)
if r != nil {
panic(r)
}
}
}()
for _, v := range items {
num2, err2 := UpdateEntityByKV(db, v.Item, v.KVs, nil)
if err = err2; err != nil {
return 0, err
}
num += num2
}
Commit(db)
}
return num, nil
}
func UpdateEntityLogically(db *DaoDB, item interface{}, kvs map[string]interface{}, userName string, conditions map[string]interface{}) (num int64, err error) {
if conditions != nil && refutil.IsFieldExist(item, model.FieldDeletedAt) {
conditions = utils.MergeMaps(conditions, map[string]interface{}{

View File

@@ -0,0 +1,59 @@
package dao
import (
"time"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
)
type PromotionStoreSku struct {
model.PromotionSku
StoreID int `orm:"column(store_id)" json:"storeID"`
}
func GenSkuPriceMapKey(storeID, skuID int) (key int64) {
return int64(storeID)*1000000 + int64(skuID)
}
func GetPromotionSkuPriceMap(db *DaoDB, vendorID int, storeIDs, skuIDs []int, fromTime, toTime time.Time) (skuPriceMap map[int64]*PromotionStoreSku, err error) {
sql := `
SELECT t2.store_id, t3.*
FROM promotion t1
JOIN promotion_store t2 ON t2.promotion_id = t1.id
JOIN promotion_sku t3 ON t3.promotion_id = t1.id
WHERE t1.deleted_at = ? AND t1.vendor_id = ? AND (t1.begin_at <= ? AND t1.end_at >= ?) AND (t1.status = ? OR t1.status = ?)`
sqlParams := []interface{}{
utils.DefaultTimeValue,
vendorID,
toTime,
fromTime,
model.PromotionStatusRemoteCreated,
}
if vendorID == model.VendorIDJX {
sqlParams = append(sqlParams, model.PromotionStatusLocalCreated)
} else {
sqlParams = append(sqlParams, model.PromotionStatusRemoteCreated)
}
if len(storeIDs) > 0 {
sql += " AND t2.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
sqlParams = append(sqlParams, storeIDs)
}
if len(skuIDs) > 0 {
sql += " AND t3.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
sqlParams = append(sqlParams, skuIDs)
}
sql += "ORDER BY t2.store_id, t3.sku_id, t3.price"
var skuPriceList []*PromotionStoreSku
if err = GetRows(db, &skuPriceList, sql, sqlParams...); err != nil {
return nil, err
}
skuPriceMap = make(map[int64]*PromotionStoreSku)
for _, v := range skuPriceList {
index := GenSkuPriceMapKey(v.StoreID, v.SkuID)
if true /*skuPriceMap[index] == nil || v.EarningPrice < skuPriceMap[index].EarningPrice*/ {
skuPriceMap[index] = v
}
}
return skuPriceMap, err
}

View File

@@ -20,8 +20,9 @@ type GoodsOrder struct {
VendorPrice int64 `json:"vendorPrice"` // 平台价
SalePrice int64 `json:"salePrice"` // 售卖价
ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付
TotalShopMoney int64 `json:"shopMoney"` // 应结金额-第三方平台结算给京西的金额(包括了所有的补贴,扣除)
TotalShopMoney int64 `json:"totalShopMoney"` // 应结金额-第三方平台结算给京西的金额(包括了所有的补贴,扣除)
PmSubsidyMoney int64 `json:"pmSubsidyMoney"` // 平台活动补贴(订单主体活动补贴+订单单条sku补贴1+
EarningPrice int64 `json:"earningPrice"` // 结算给门店老板的钱(未扣除可能的三方配送费)
Weight int `json:"weight"` // 单位为克
ConsigneeName string `orm:"size(32)" json:"consigneeName"`
ConsigneeMobile string `orm:"size(32)" json:"consigneeMobile"`

View File

@@ -172,7 +172,7 @@ type IStoreManager interface {
// 所有非以SyncRefresh开头的函数不用自己清理sync_status标记VendorSync统一处理
type IPurchasePlatformHandler interface {
IPurchasePlatformPromotionHandler
IPurchasePlatformActHandler
GetVendorID() int
GetStatusFromVendorStatus(vendorStatus string) int

View File

@@ -1,24 +1,83 @@
package partner
import (
"time"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
)
type IPurchasePlatformPromotionHandler interface {
// 如果是单品级活动actOrderRules为空
// 如果是订单级活动actStoreSku可以为空表示不限制SKU
CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error)
UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error)
// 取消整个京西活动
CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error)
type IPurchasePlatformActHandler interface {
// // 如果是单品级活动actOrderRules为空
// // 如果是订单级活动actStoreSku可以为空表示不限制SKU
// CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSku []*model.ActStoreSku2) (err error)
// UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSku []*model.ActStoreSku2) (err error)
// // 取消整个京西活动
// CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (err error)
SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error)
}
func ActStoreSku2Map(actStoreSku []*model.ActStoreSku2) (actStoreSkuMap map[int][]*model.ActStoreSku2) {
func SplitActStoreSku(actStoreSkuList []*model.ActStoreSku2) (actStoreSkuMap map[int][]*model.ActStoreSku2) {
actStoreSkuMap = make(map[int][]*model.ActStoreSku2)
for _, storeSku := range actStoreSku {
actStoreSkuMap[storeSku.StoreID] = append(actStoreSkuMap[storeSku.StoreID], storeSku)
for _, v := range actStoreSkuList {
actStoreSkuMap[v.StoreID] = append(actStoreSkuMap[v.StoreID], v)
}
return actStoreSkuMap
}
func SplitActStoreSku2List(actStoreSkuList []*model.ActStoreSku2) (actStoreSkuListList [][]*model.ActStoreSku2) {
actStoreSkuMap := SplitActStoreSku(actStoreSkuList)
for _, v := range actStoreSkuMap {
actStoreSkuListList = append(actStoreSkuListList, v)
}
return actStoreSkuListList
}
func Act2ActMap(act *model.Act2) (actMap *model.ActMap) {
actMap = &model.ActMap{}
actMap.ID = act.MapID
return actMap
}
func ActStoreSku2ActStoreSkuMap(actStoreSku *model.ActStoreSku2) (actStoreSkuMap *model.ActStoreSkuMap) {
actStoreSkuMap = &model.ActStoreSkuMap{}
actStoreSkuMap.ID = actStoreSku.MapID
return actStoreSkuMap
}
func Act2Update(act *model.Act2, syncStatus int) (item *dao.KVUpdateItem) {
kvs := map[string]interface{}{
model.FieldSyncStatus: 0,
}
if syncStatus == model.SyncFlagDeletedMask {
kvs[model.FieldDeletedAt] = time.Now()
} else if syncStatus == model.SyncFlagNewMask {
kvs[model.FieldVendorActID] = act.VendorActID
}
item = &dao.KVUpdateItem{
Item: Act2ActMap(act),
KVs: kvs,
}
return item
}
func ActStoreSku2Update(actStoreSkuList []*model.ActStoreSku2, syncStatus int) (items []*dao.KVUpdateItem) {
for _, v := range actStoreSkuList {
kvs := map[string]interface{}{
model.FieldSyncStatus: 0,
}
if syncStatus == model.SyncFlagDeletedMask {
kvs[model.FieldDeletedAt] = time.Now()
} else if syncStatus == model.SyncFlagNewMask {
kvs[model.FieldVendorActID] = v.VendorActID
}
items = append(items, &dao.KVUpdateItem{
Item: ActStoreSku2ActStoreSkuMap(v),
KVs: kvs,
})
}
return items
}

View File

@@ -102,16 +102,20 @@ func ActivitySkuUpdateBatch(activityID int64, actSkuInfoList []*ebaiapi.Activity
return api.EbaiAPI.ActivitySkuUpdateBatch(activityID, actSkuInfoList)
}
func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSku []*model.ActStoreSku2) (err error) {
activity := act2EbaiActivity(act, actOrderRules)
if act.Type < model.ActOrderBegin {
actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku)
actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku)
task := tasksch.NewParallelTask("ebai CreateAct", nil, ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
store := batchItemList[0].(*model.ActStore2)
store.VendorActID, err = createOneShopAct(utils.Int2Str(store.StoreID), activity, actStoreSkuMap[store.StoreID])
list := batchItemList[0].([]*model.ActStoreSku2)
var vendorActID string
vendorActID, err = createOneShopAct(utils.Int2Str(list[0].StoreID), activity, list)
for _, v := range list {
v.VendorActID = vendorActID
}
return nil, err
}, actStoreMap)
}, actStoreSkuListList)
tasksch.HandleTask(task, parentTask, true).Run()
_, err = task.GetResult(0)
} else {
@@ -120,67 +124,55 @@ func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.I
return err
}
func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
if act.Type < model.ActOrderBegin {
actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku)
if len(actStoreMap2Remove) > 0 {
if err = c.CancelAct(ctx, parentTask, act, actStoreMap2Remove, nil); err != nil {
return err
}
for _, v := range actStoreMap2Remove {
delete(actStoreSkuMap, v.StoreID)
}
}
if len(actStoreMap2Add) > 0 {
if err = c.CreateAct(ctx, parentTask, act, actOrderRules, actStoreMap2Add, actStoreSku); err != nil {
return err
}
for _, v := range actStoreMap2Add {
delete(actStoreSkuMap, v.StoreID)
}
}
task := tasksch.NewParallelTask("ebai UpdateAct", nil, ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
v := batchItemList[0].(*model.ActStore2)
if storeSkus := actStoreSkuMap[v.StoreID]; storeSkus != nil {
if list := actStoreSu2Ebai4Delete(storeSkus); len(list) > 0 {
if _, err = ActivitySkuDeleteBatch(utils.Str2Int64(v.VendorActID), utils.Int2Str(v.StoreID), 0, list, false); err != nil {
return nil, err
}
}
if list := actStoreSu2Ebai4Add(storeSkus); len(list) > 0 {
if _, err = ActivitySkuAddBatch(utils.Str2Int64(v.VendorActID), utils.Int2Str(v.StoreID), 0, actType2Ebai(act.Type), list, false); err != nil {
return nil, err
}
}
if list := actStoreSu2Ebai4Update(storeSkus); len(list) > 0 {
if _, err = ActivitySkuUpdateBatch(utils.Str2Int64(v.VendorActID), list); err != nil {
return nil, err
}
}
}
return nil, err
}, actStoreMap2Update)
tasksch.HandleTask(task, parentTask, true).Run()
_, err = task.GetResult(0)
} else {
func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSku []*model.ActStoreSku2) (err error) {
// if act.Type < model.ActOrderBegin {
// actStoreSkuMap := partner.SplitActStoreSku(actStoreSku)
// task := tasksch.NewParallelTask("ebai UpdateAct", nil, ctx,
// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
// v := batchItemList[0].(*model.ActStore2)
// if storeSkus := actStoreSkuMap[v.StoreID]; storeSkus != nil {
// if list := actStoreSu2Ebai4Delete(storeSkus); len(list) > 0 {
// if _, err = ActivitySkuDeleteBatch(utils.Str2Int64(v.VendorActID), utils.Int2Str(v.StoreID), 0, list, false); err != nil {
// return nil, err
// }
// }
// if list := actStoreSu2Ebai4Add(storeSkus); len(list) > 0 {
// if _, err = ActivitySkuAddBatch(utils.Str2Int64(v.VendorActID), utils.Int2Str(v.StoreID), 0, actType2Ebai(act.Type), list, false); err != nil {
// return nil, err
// }
// }
// if list := actStoreSu2Ebai4Update(storeSkus); len(list) > 0 {
// if _, err = ActivitySkuUpdateBatch(utils.Str2Int64(v.VendorActID), list); err != nil {
// return nil, err
// }
// }
// }
// return nil, err
// }, actStoreMap2Update)
// tasksch.HandleTask(task, parentTask, true).Run()
// _, err = task.GetResult(0)
// } else {
}
// }
return err
}
func (c *PurchaseHandler) CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
if act.Type < model.ActOrderBegin {
task := tasksch.NewParallelTask("ebai DeleteAct", nil, ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
v := batchItemList[0].(*model.ActStore2)
if globals.EnableEbaiStoreWrite {
err = api.EbaiAPI.ActivityDisable(utils.Str2Int64(v.VendorActID), utils.Int2Str(v.StoreID), 0, 0)
}
return nil, err
}, actStoreMap)
tasksch.HandleTask(task, parentTask, true).Run()
_, err = task.GetResult(0)
}
func (c *PurchaseHandler) CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (err error) {
// if act.Type < model.ActOrderBegin {
// task := tasksch.NewParallelTask("ebai DeleteAct", nil, ctx,
// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
// v := batchItemList[0].(*model.ActStore2)
// if globals.EnableEbaiStoreWrite {
// err = api.EbaiAPI.ActivityDisable(utils.Str2Int64(v.VendorActID), utils.Int2Str(v.StoreID), 0, 0)
// }
// return nil, err
// }, actStoreMap)
// tasksch.HandleTask(task, parentTask, true).Run()
// _, err = task.GetResult(0)
// }
return err
}
func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) {
return nil
}

View File

@@ -496,9 +496,9 @@ func genSkuParamsFromStoreSkuInfo(storeSku *tStoreSkuFullInfo) (params map[strin
params["status"] = jxSkuStatus2Ebai(jxutils.MergeSkuStatus(storeSku.SkuStatus, storeSku.Status))
}
// todo 饿百如果给的UPC是空要报错但如果我要删除UPC怎么弄
if storeSku.Upc != "" {
params["upc"] = storeSku.Upc
}
// if storeSku.Upc != "" {
// params["upc"] = storeSku.Upc
// }
return params
}

View File

@@ -6,14 +6,6 @@ import (
"git.rosy.net.cn/jx-callback/business/model"
)
func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
return err
}
func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
return err
}
func (c *PurchaseHandler) CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
return err
func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) {
return nil
}

View File

@@ -3,6 +3,9 @@ package jd
import (
"time"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/globals"
@@ -15,6 +18,12 @@ import (
"git.rosy.net.cn/jx-callback/business/model"
)
type LogicUpdateInfo struct {
Item interface{}
KVs map[string]interface{}
Condition map[string]interface{}
}
func CreatePromotionInfos(promotionType int, name string, beginDate, endDate time.Time, outInfoId, advertising, traceId string) (infoId int64, err error) {
if globals.EnableJdStoreWrite {
if promotionType == model.ActSkuDirectDown {
@@ -124,60 +133,131 @@ func storeSku2Jd(actStoreSku []*model.ActStoreSku2, handler func(syncStatus int)
return jdActStoreSku
}
func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
traceID := getTraceID(ctx)
func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSku []*model.ActStoreSku2) (err error) {
if act.Type < model.ActOrderBegin {
outInfoID := utils.Int2Str(act.ID)
infoID, err2 := CreatePromotionInfos(act.Type, act.Name, act.BeginAt, act.EndAt, outInfoID, act.Advertising, traceID)
if err = err2; err == nil {
act.VendorActID = utils.Int64ToStr(infoID)
if err = CreatePromotionRules(act.Type, infoID, "", act.LimitDevice, act.LimitPin, act.LimitCount, act.LimitDaily, traceID); err == nil {
if _, err = CreatePromotionSku(act.Type, infoID, "", storeSku2Jd(actStoreSku, model.IsSyncStatusNeedCreate), traceID); err == nil {
err = ConfirmPromotion(act.Type, infoID, "", traceID)
act.VendorActID, err = createSkuAct(ctx, act, actStoreSku)
} else {
}
return err
}
func createSkuAct(ctx *jxcontext.Context, act *model.Act2, actStoreSku []*model.ActStoreSku2) (vendorActID string, err error) {
traceID := getTraceID(ctx)
outInfoID := ""
if act.VendorActID == "" {
outInfoID = utils.Int2Str(act.ID)
}
infoID, err2 := CreatePromotionInfos(act.Type, act.Name, act.BeginAt, act.EndAt, outInfoID, act.Advertising, traceID)
if err = err2; err == nil {
vendorActID = utils.Int64ToStr(infoID)
if err = CreatePromotionRules(act.Type, infoID, "", act.LimitDevice, act.LimitPin, act.LimitCount, act.LimitDaily, traceID); err == nil {
if _, err = CreatePromotionSku(act.Type, infoID, "", storeSku2Jd(actStoreSku, model.IsSyncStatusNeedCreate), traceID); err == nil {
if err = ConfirmPromotion(act.Type, infoID, "", traceID); err == nil {
for _, v := range actStoreSku {
v.VendorActID = vendorActID
}
}
}
}
} else {
}
return vendorActID, err
}
func cancelSkuActSkus(ctx *jxcontext.Context, actType int, vendorActID string, actStoreSku []*model.ActStoreSku2) (err error) {
if skuList := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(skuList) > 0 {
err = CancelPromotionSku(actType, utils.Str2Int64(vendorActID), "", skuList, getTraceID(ctx))
}
return err
}
func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
traceID := getTraceID(ctx)
func cancelSkuAct(ctx *jxcontext.Context, actType int, vendorActID string) (err error) {
err = CancelPromotion(actType, utils.Str2Int64(vendorActID), "", getTraceID(ctx))
return err
}
func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSku []*model.ActStoreSku2) (err error) {
return err
}
func (c *PurchaseHandler) CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (err error) {
if act.Type < model.ActOrderBegin {
outInfoID := utils.Int2Str(act.ID)
if !utils.IsTimeZero(act.EndAt) {
if err = AdjustPromotionTime(act.Type, 0, outInfoID, act.EndAt, traceID); err != nil {
return err
}
}
if toBeDeleted := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(toBeDeleted) > 0 {
if err = CancelPromotionSku(act.Type, 0, outInfoID, toBeDeleted, traceID); err != nil {
return err
}
}
// if toBeAdded := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(toBeAdded) > 0 {
// if _, err = CreatePromotionSku(act.Type, 0, outInfoID, toBeAdded, traceID); err != nil {
// return err
// }
// }
// if toBeUpdated := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(toBeUpdated) > 0 {
// if _, err = AdjustPromotionSku(act.Type, 0, outInfoID, toBeUpdated, traceID); err != nil {
// return err
// }
// }
} else {
err = CancelPromotion(act.Type, 0, outInfoID, getTraceID(ctx))
}
return err
}
func (c *PurchaseHandler) CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
traceID := getTraceID(ctx)
if act.Type < model.ActOrderBegin {
outInfoID := utils.Int2Str(act.ID)
err = CancelPromotion(act.Type, 0, outInfoID, traceID)
func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) {
globals.SugarLogger.Debugf("jd SyncAct, actID:%d", act.ID)
vendorActInfoMap := make(map[string][]*model.ActStoreSku2)
deleteActInfoMap := make(map[string][]*model.ActStoreSku2)
var actStoreSkuList4Create []*model.ActStoreSku2
var updateItems []*dao.KVUpdateItem
actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuList)
for storeID := range actStoreSkuMap {
for _, actStoreSku := range actStoreSkuMap[storeID] {
vendorActInfoMap[actStoreSku.VendorActID] = append(vendorActInfoMap[actStoreSku.VendorActID], actStoreSku)
if model.IsSyncStatusNeedCreate(actStoreSku.SyncStatus) {
actStoreSkuList4Create = append(actStoreSkuList4Create, actStoreSku)
} else if model.IsSyncStatusNeedDelete(actStoreSku.SyncStatus) {
vendorActID := actStoreSku.VendorActID
if vendorActID == "" {
vendorActID = act.VendorActID
}
deleteActInfoMap[vendorActID] = append(deleteActInfoMap[vendorActID], actStoreSku)
}
}
}
err = func() (err error) {
if model.IsSyncStatusNeedCreate(act.SyncStatus) {
if act.VendorActID, err = createSkuAct(ctx, act, actStoreSkuList4Create); err != nil {
return err
}
updateItems = append(updateItems, partner.ActStoreSku2Update(actStoreSkuList4Create, model.SyncFlagNewMask)...)
updateItems = append(updateItems, partner.Act2Update(act, model.SyncFlagNewMask))
} else if model.IsSyncStatusNeedDelete(act.SyncStatus) {
for vendorActID := range vendorActInfoMap {
if vendorActID != "" {
if err = cancelSkuAct(ctx, act.Type, vendorActID); err != nil {
return err
}
}
}
for _, actStoreSkuList := range vendorActInfoMap {
updateItems = append(updateItems, partner.ActStoreSku2Update(actStoreSkuList, model.SyncFlagDeletedMask)...)
}
updateItems = append(updateItems, partner.Act2Update(act, model.SyncFlagDeletedMask))
} else if model.IsSyncStatusNeedUpdate(act.SyncStatus) {
// globals.SugarLogger.Debug(utils.Format4Output(updateItems, false))
for vendorActID := range deleteActInfoMap {
if vendorActID != "" {
if len(vendorActInfoMap[vendorActID]) == len(deleteActInfoMap[vendorActID]) {
err = cancelSkuAct(ctx, act.Type, vendorActID)
} else {
err = cancelSkuActSkus(ctx, act.Type, vendorActID, deleteActInfoMap[vendorActID])
}
if err != nil {
return err
}
}
updateItems = append(updateItems, partner.ActStoreSku2Update(deleteActInfoMap[vendorActID], model.SyncFlagDeletedMask)...)
}
if len(actStoreSkuList4Create) > 0 {
if _, err = createSkuAct(ctx, act, actStoreSkuList4Create); err != nil {
return err
}
updateItems = append(updateItems, partner.ActStoreSku2Update(actStoreSkuList4Create, model.SyncFlagNewMask)...)
}
updateItems = append(updateItems, partner.Act2Update(act, model.SyncFlagModifiedMask))
}
return nil
}()
db := dao.GetDB()
_, err2 := dao.BatchUpdateEntityByKV(db, updateItems)
if err == nil {
err = err2
}
return err
}

View File

@@ -43,6 +43,21 @@ func (c *PurchaseHandler) OnOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi
return retVal
}
func (c *PurchaseHandler) updateOrderFinancialInfo(orderID string) (err error) {
order := &model.GoodsOrder{
VendorOrderID: orderID,
VendorID: model.VendorIDJD,
}
orderSettlement, err := api.JdAPI.OrderShoudSettlementService2(orderID)
if err == nil {
if orderSettlement != nil {
updateOrderBySettleMent(order, orderSettlement)
err = partner.CurOrderManager.UpdateOrderFields(order, []string{"TotalShopMoney", "PmSubsidyMoney"})
}
}
return err
}
func (c *PurchaseHandler) onOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) {
status := c.callbackMsg2Status(msg)
if jdapi.StatusIDNewOrder == msg.StatusID {
@@ -53,6 +68,7 @@ func (c *PurchaseHandler) onOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi
}
if msg.MsgURL == jdapi.CallbackMsgOrderAccounting {
retVal = c.OnFinancialMsg(msg)
retVal = jdapi.Err2CallbackResponse(c.updateOrderFinancialInfo(msg.BillID), status.VendorStatus)
} else if msg.MsgURL == jdapi.CallbackMsgAfterSaleBillStatus {
retVal = c.OnAfsOrderMsg(msg)
} else {
@@ -77,6 +93,13 @@ func (c *PurchaseHandler) onOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi
return retVal
}
func updateOrderBySettleMent(order *model.GoodsOrder, orderSettlement *jdapi.OrderSettlementInfo) {
if orderSettlement != nil {
order.TotalShopMoney = orderSettlement.SettlementAmount
order.PmSubsidyMoney = orderSettlement.PlatOrderGoodsDiscountMoney + orderSettlement.PlatSkuGoodsDiscountMoney
}
}
func (c *PurchaseHandler) getOrder(orderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) {
globals.SugarLogger.Debugf("jd getOrder orderID:%s", orderID)
var (
@@ -104,10 +127,7 @@ func (c *PurchaseHandler) getOrder(orderID string) (order *model.GoodsOrder, ord
task.Run()
task.GetResult(0)
if order != nil {
if orderSettlement != nil {
order.TotalShopMoney = orderSettlement.SettlementAmount
order.PmSubsidyMoney = orderSettlement.PlatOrderGoodsDiscountMoney + orderSettlement.PlatSkuGoodsDiscountMoney
}
updateOrderBySettleMent(order, orderSettlement)
}
// if orderMap, err = api.JdAPI.QuerySingleOrder(orderID); err == nil {
// globals.SugarLogger.Debugf("jd getOrder2 orderID:%s", orderID)

View File

@@ -70,6 +70,9 @@ func (c *PurchaseHandler) onAfsOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jd
afsInfo, err := api.JdAPI.GetAfsService2(msg.BillID)
if err == nil {
status := c.callbackAfsMsg2Status(msg, afsInfo)
if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 {
return nil
}
if status.Status == model.AfsOrderStatusWait4Approve || status.Status == model.AfsOrderStatusNew {
afsOrder := c.buildAfsOrder(afsInfo)
err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, status)

View File

@@ -304,17 +304,17 @@ func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorStoreID s
// 当前京东的storeCrud消息不会在门店状态改变时发送所以意义不大先放在这里
func (c *PurchaseHandler) OnStoreMsg(msg *jdapi.CallbackOrderMsg) (response *jdapi.CallbackResponse) {
var err error
if msg.StatusID == jdapi.StatusIDUpdateStore {
var storeStatus int
vendorStoreID := msg.BillID
if storeStatus, err = c.GetStoreStatus(jxcontext.AdminCtx, vendorStoreID); err == nil {
err = partner.CurStoreManager.OnStoreStatusChanged(vendorStoreID, model.VendorIDJD, storeStatus)
} else {
// 可能在门店删除的情况下会出查不到门店的错误
if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == 4 {
err = nil
}
}
}
// if msg.StatusID == jdapi.StatusIDUpdateStore {
// var storeStatus int
// vendorStoreID := msg.BillID
// if storeStatus, err = c.GetStoreStatus(jxcontext.AdminCtx, vendorStoreID); err == nil {
// err = partner.CurStoreManager.OnStoreStatusChanged(vendorStoreID, model.VendorIDJD, storeStatus)
// } else {
// // 可能在门店删除的情况下会出查不到门店的错误
// if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == 4 {
// err = nil
// }
// }
// }
return jdapi.Err2CallbackResponse(err, "")
}

View File

@@ -7,7 +7,6 @@ import (
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
)
@@ -60,11 +59,11 @@ func isCreateOrUpdate(syncStatus int) bool {
return model.IsSyncStatusNeedCreate(syncStatus) || model.IsSyncStatusNeedUpdate(syncStatus)
}
func createOneShopAct(act *model.Act2, storeMap *model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
func createOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*model.ActStoreSku2) (err error) {
actData := storeSku2ActData(act, actStoreSku, isCreateOrUpdate)
if len(actData) > 0 {
if globals.EnableMtwmStoreWrite {
actResult, err2 := api.MtwmAPI.RetailDiscountBatchSave(storeMap.VendorStoreID, actData)
actResult, err2 := api.MtwmAPI.RetailDiscountBatchSave(vendorStoreID, actData)
if err = err2; err != nil {
return err
}
@@ -86,84 +85,13 @@ func createOneShopAct(act *model.Act2, storeMap *model.ActStore2, actStoreSku []
return err
}
func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
globals.SugarLogger.Debugf("mtwm CreateAct actID:%d", act.ID)
if act.Type < model.ActOrderBegin {
actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku)
task := tasksch.NewParallelTask("mtwm CreateAct", nil, ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
store := batchItemList[0].(*model.ActStore2)
err = createOneShopAct(act, store, actStoreSkuMap[store.StoreID])
return nil, err
}, actStoreMap)
tasksch.HandleTask(task, parentTask, true).Run()
_, err = task.GetResult(0)
} else {
func cancelOneShopAct(ctx *jxcontext.Context, vendorStoreID string, actStoreSku []*model.ActStoreSku2) (err error) {
if list := storeSku2ActData4Delete(actStoreSku, model.IsSyncStatusNeedDelete); len(list) > 0 {
err = api.MtwmAPI.RetailDiscountDelete(vendorStoreID, list)
}
return err
}
func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
if act.Type < model.ActOrderBegin {
actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku)
if len(actStoreMap2Remove) > 0 {
if err = c.CancelAct(ctx, parentTask, act, actStoreMap2Remove, nil); err != nil {
return err
}
for _, v := range actStoreMap2Remove {
delete(actStoreSkuMap, v.StoreID)
}
}
if len(actStoreMap2Add) > 0 {
if err = c.CreateAct(ctx, parentTask, act, actOrderRules, actStoreMap2Add, actStoreSku); err != nil {
return err
}
for _, v := range actStoreMap2Add {
delete(actStoreSkuMap, v.StoreID)
}
}
task := tasksch.NewParallelTask("mtwm UpdateAct", nil, ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
v := batchItemList[0].(*model.ActStore2)
if storeSkus := actStoreSkuMap[v.StoreID]; storeSkus != nil {
if list := storeSku2ActData4Delete(storeSkus, model.IsSyncStatusNeedDelete); len(list) > 0 {
if err = api.MtwmAPI.RetailDiscountDelete(v.VendorStoreID, list); err != nil {
return nil, err
}
}
if err = createOneShopAct(act, v, actStoreSkuMap[v.StoreID]); err != nil {
return nil, err
}
}
return nil, err
}, actStoreMap2Update)
tasksch.HandleTask(task, parentTask, true).Run()
_, err = task.GetResult(0)
} else {
}
return err
}
func (c *PurchaseHandler) CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
if act.Type < model.ActOrderBegin {
actStoreSkuMap := partner.ActStoreSku2Map(actStoreSku)
task := tasksch.NewParallelTask("mtwm DeleteAct", nil, ctx,
func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
v := batchItemList[0].(*model.ActStore2)
actIDList := storeSku2ActData4Delete(actStoreSkuMap[v.StoreID], nil)
if len(actIDList) > 0 {
if globals.EnableMtwmStoreWrite {
err = api.MtwmAPI.RetailDiscountDelete(v.VendorStoreID, actIDList)
}
}
return nil, err
}, actStoreMap)
tasksch.HandleTask(task, parentTask, true).Run()
_, err = task.GetResult(0)
} else {
}
return err
func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) {
return nil
}

View File

@@ -6,14 +6,6 @@ import (
"git.rosy.net.cn/jx-callback/business/model"
)
func (c *PurchaseHandler) CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
return err
}
func (c *PurchaseHandler) UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreMap2Remove, actStoreMap2Add, actStoreMap2Update []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
return err
}
func (c *PurchaseHandler) CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreMap []*model.ActStore2, actStoreSku []*model.ActStoreSku2) (err error) {
return err
func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) {
return nil
}

View File

@@ -48,7 +48,10 @@ type StoreSkuController struct {
// @router /GetStoreSkus [get]
func (c *StoreSkuController) GetStoreSkus() {
c.callGetStoreSkus(func(params *tStoreSkuGetStoreSkusParams) (retVal interface{}, errCode string, err error) {
retVal, err = cms.GetStoreSkus(params.Ctx, params.StoreID, params.IsFocus, params.Keyword, params.IsBySku, params.MapData, params.Offset, params.PageSize)
var skuIDs []int
if err = jxutils.Strings2Objs(params.SkuIDs, &skuIDs); err == nil {
retVal, err = cms.GetStoreSkus(params.Ctx, params.StoreID, skuIDs, params.IsFocus, params.Keyword, params.IsBySku, params.MapData, params.Offset, params.PageSize)
}
return retVal, "", err
})
}
@@ -84,9 +87,9 @@ func (c *StoreSkuController) GetStoreSkus() {
// @router /GetStoresSkus [get]
func (c *StoreSkuController) GetStoresSkus() {
c.callGetStoresSkus(func(params *tStoreSkuGetStoresSkusParams) (retVal interface{}, errCode string, err error) {
var storeIDs []int
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs); err == nil {
retVal, err = cms.GetStoresSkus(params.Ctx, storeIDs, params.IsFocus, params.Keyword, params.IsBySku, params.MapData, params.Offset, params.PageSize)
var storeIDs, skuIDs []int
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.SkuIDs, &skuIDs); err == nil {
retVal, err = cms.GetStoresSkus(params.Ctx, storeIDs, skuIDs, params.IsFocus, params.Keyword, params.IsBySku, params.MapData, params.Offset, params.PageSize)
}
return retVal, "", err
})

View File

@@ -437,6 +437,26 @@ func (c *OrderController) RefreshOrderRealMobile() {
})
}
// @Title 刷新订单平台结算信息
// @Description 刷新订单平台结算信息
// @Param token header string true "认证token"
// @Param fromTime formData string true "起始时间"
// @Param toTime formData string false "结束时间"
// @Param isAsync formData bool true "是否异步操作"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /RefreshOrderFinancial [put]
func (c *OrderController) RefreshOrderFinancial() {
c.callRefreshOrderFinancial(func(params *tOrderRefreshOrderFinancialParams) (retVal interface{}, errCode string, err error) {
timeList, err2 := jxutils.BatchStr2Time(params.FromTime, params.ToTime)
if err = err2; err == nil {
retVal, err = misc.RefreshOrderFinancial(params.Ctx, timeList[0], timeList[1], params.IsAsync, params.IsContinueWhenError)
}
return retVal, "", err
})
}
// @Title 设置订单打印状态
// @Description 同步商家SKU类别
// @Param token header string true "认证token"

View File

@@ -5,6 +5,10 @@ After=network.target
After=mysql.service
[Service]
LimitCORE=infinity
LimitNOFILE=100000
LimitNPROC=100000
Environment="GOPATH=/home/ubuntu/go/"
Type=simple
User=ubuntu

View File

@@ -48,7 +48,7 @@ func Init() {
// 如下语句建表时要出错INDEX名字太长了暂时放一下必须放最后一句
orm.RegisterModel(&model.OrderFinancial{}, &model.AfsOrder{}, &model.OrderDiscountFinancial{}, &model.OrderSkuFinancial{})
// orm.RegisterModel(&model.Act{}, &model.ActOrderRule{}, &model.ActStoreSku{})
// orm.RegisterModel(&model.ActMap{}, &model.ActStoreMap{}, &model.ActStoreSkuMap{})
// orm.RegisterModel(&model.ActMap{}, &model.ActStoreSkuMap{})
// create table
orm.RunSyncdb("default", false, true)
}

View File

@@ -20,6 +20,7 @@ import (
"git.rosy.net.cn/jx-callback/globals/beegodb"
_ "git.rosy.net.cn/jx-callback/routers"
// _ "git.rosy.net.cn/jx-callback/business/jxstore/act"
_ "git.rosy.net.cn/jx-callback/business/partner/printer/feie"
_ "git.rosy.net.cn/jx-callback/business/partner/printer/xiaowm"
_ "git.rosy.net.cn/jx-callback/business/partner/printer/yilianyun"

View File

@@ -772,6 +772,15 @@ func init() {
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"],
beego.ControllerComments{
Method: "RefreshOrderFinancial",
Router: `/RefreshOrderFinancial`,
AllowHTTPMethods: []string{"put"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"],
beego.ControllerComments{
Method: "RefreshOrderRealMobile",