Commit c8399857 by 杨树贤

价格逻辑修改

parent acacf9fb
...@@ -86,8 +86,9 @@ type DiscountRatio struct { ...@@ -86,8 +86,9 @@ type DiscountRatio struct {
} }
type PriceRatio struct { type PriceRatio struct {
Ratio float64 `json:"ratio"` Ratio float64 `json:"ratio"`
RatioUsd float64 `json:"ratio_usd"` RatioUsd float64 `json:"ratio_usd"`
Purchases int64 `json:"purchases,omitempty"`
} }
type PriceActivity struct { type PriceActivity struct {
......
...@@ -7,8 +7,6 @@ import ( ...@@ -7,8 +7,6 @@ import (
"go_sku_server/pkg/gredis" "go_sku_server/pkg/gredis"
"go_sku_server/pkg/logger" "go_sku_server/pkg/logger"
_ "go_sku_server/pkg/mongo" _ "go_sku_server/pkg/mongo"
"go_sku_server/service/sorter"
"strconv"
"strings" "strings"
"github.com/gomodule/redigo/redis" "github.com/gomodule/redigo/redis"
...@@ -211,10 +209,8 @@ func (ls *LyService) GetCoefficientAndPrice(sku model.LySku) model.LySku { ...@@ -211,10 +209,8 @@ func (ls *LyService) GetCoefficientAndPrice(sku model.LySku) model.LySku {
//如果没有成本价字段,就要去生成阶梯价格 //如果没有成本价字段,就要去生成阶梯价格
if len(ladderPrice) > 0 { if len(ladderPrice) > 0 {
if ladderPrice[0].PriceCostUs == 0 && ladderPrice[0].PriceCostCn == 0 { if ladderPrice[0].PriceCostUs == 0 && ladderPrice[0].PriceCostCn == 0 {
generatedLadderPrice, priceRatio := priceService.GenerateLadderPrice(sku) sku = priceService.GenerateLadderPrice(sku)
ladderPrice = generatedLadderPrice ladderPrice = sku.LadderPrice
sku.PriceRatio = priceRatio
sku.PriceRatioSort = -1
} }
} }
data = make([]model.LadderPrice, len(ladderPrice)) data = make([]model.LadderPrice, len(ladderPrice))
...@@ -259,154 +255,14 @@ func (ls *LyService) GetCoefficientAndPrice(sku model.LySku) model.LySku { ...@@ -259,154 +255,14 @@ func (ls *LyService) GetCoefficientAndPrice(sku model.LySku) model.LySku {
redisCon := gredis.Conn("default_r") redisCon := gredis.Conn("default_r")
defer redisCon.Close() defer redisCon.Close()
/**
**/
sku = priceService.GetDiscountRatio(sku) sku = priceService.GetDiscountRatio(sku)
/** /**
再去找售价组系数 再去找售价组系数
**/ **/
sku, priceRatioList := priceService.GetPriceRatio(sku)
//找一个标志位,因为默认的全局折扣系数的数据格式和非全局的是不一样的 /** 这里是供应商系数,先保留这块逻辑 **/
isDefaultPriceRatio := false
priceRatioCache, _ := redis.String(redisCon.Do("HGET", "magic_cube_price_rule_channel", sku.SupplierId))
checkNullRation := gjson.Get(priceRatioCache, "ladder_price").String()
//如果这个渠道没有对应的折扣系数,那么就去读取全局的
if priceRatioCache == "" || checkNullRation == "{}" {
isDefaultPriceRatio = true
priceRatioCache, _ = redis.String(redisCon.Do("GET", "magic_cube_price_rule_channel_default"))
}
var priceRatioSort int
//这个就是最终要获取到的价格系数
var priceRatioList []model.PriceRatio
//是否找到系数的标志位
foundRatio := false
//如果只有默认系数,那么就去找默认系数
if isDefaultPriceRatio {
} else {
//拿到系数以后,就要去计算
//拿出里面的所有排序
priceRatioSortMap := gjson.Get(priceRatioCache, "ladder_price").Map()
var sortNumbers []int
for sortNumberString, _ := range priceRatioSortMap {
sortNumber, _ := strconv.Atoi(sortNumberString)
sortNumbers = append(sortNumbers, sortNumber)
}
//然后确定排序
sortNumbers = sorter.IntSliceSortDesc(sortNumbers)
//确定排序以后,就可以进行按排序(从大到小)取系数
outerLoop:
for _, sortNumber := range sortNumbers {
priceRatioSort = sortNumber
priceRatioList = nil
sortString := strconv.Itoa(sortNumber)
priceRatioArr := gjson.Get(priceRatioCache, "ladder_price."+sortString).Array()
for _, value := range priceRatioArr {
var priceRatio model.PriceRatio
priceRatio.Ratio = gjson.Get(value.String(), "ratio").Float()
priceRatio.RatioUsd = gjson.Get(value.String(), "ratio_usd").Float()
priceRatioList = append(priceRatioList, priceRatio)
}
var hasSpecialCheck = false
//判断是否有符合的商品名称
goodsNames := gjson.Get(priceRatioCache, "goods_name."+sortString).String()
if goodsNames != "" {
hasSpecialCheck = true
goodsNameList := strings.Split(goodsNames, "@€@")
//找到有对应的商品名称,那么优先级肯定是最高的了
if php2go.InArray(sku.GoodsName, goodsNameList) {
foundRatio = true
break
}
}
//判断是否有符合的标准品牌ID
brandIds := gjson.Get(priceRatioCache, "brand."+sortString).String()
if brandIds != "" {
hasSpecialCheck = true
standardBrandIdList := strings.Split(brandIds, ",")
standardBrandId := strconv.Itoa(sku.StandardBrand.StandardBrandId)
//找到有对应的品牌,那么优先级肯定是最高的了
if php2go.InArray(standardBrandId, standardBrandIdList) {
foundRatio = true
break
}
}
//判断是否有符合的eccn
eccns := gjson.Get(priceRatioCache, "eccn."+sortString).String()
if eccns != "" {
hasSpecialCheck = true
eccnList := strings.Split(eccns, ",")
//找到有对应的eccn,那么优先级肯定是最高的了
for _, eccn := range eccnList {
//判断是否有百分号匹配
//如果是纯%,那就是不对的,要跳过
if strings.Replace(eccn, "%", "", 10) == "" {
continue
}
if strings.Contains(eccn, "%") {
hasPrefix := strings.HasPrefix(eccn, "%")
hasSuffix := strings.HasSuffix(eccn, "%")
if hasPrefix && hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10)
if strings.Contains(sku.Eccn, eccn) {
foundRatio = true
break outerLoop
}
}
if hasPrefix && !hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10)
if strings.HasSuffix(sku.Eccn, eccn) {
foundRatio = true
break outerLoop
}
}
if !hasPrefix && hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10)
if strings.HasPrefix(sku.Eccn, eccn) {
foundRatio = true
break outerLoop
}
}
} else {
if sku.Eccn == eccn {
foundRatio = true
break outerLoop
}
}
}
}
//如果没有设置品牌和商品,那么这个优先级高的就会覆盖下面的了,不需要再去判断品牌和型号了
if hasSpecialCheck {
continue
}
foundRatio = true
break
}
}
//找不到特定的系数,那就去找全局的
if !foundRatio {
priceRatioCache, _ = redis.String(redisCon.Do("GET", "magic_cube_price_rule_channel_default"))
priceRatioArr := gjson.Get(priceRatioCache, "ladder_price").Array()
priceRatioList = nil
for _, value := range priceRatioArr {
var priceRatio model.PriceRatio
priceRatio.Ratio = gjson.Get(value.String(), "ratio").Float()
priceRatio.RatioUsd = gjson.Get(value.String(), "ratio_usd").Float()
priceRatioList = append(priceRatioList, priceRatio)
}
priceRatioSort = -1
}
sku.PriceRatio = priceRatioList
sku.PriceRatioSort = priceRatioSort
//这里是供应商系数,先保留这块逻辑
ratio, _ := redis.String(redisCon.Do("HGET", "pool_supplier_ratio", sku.SupplierId)) ratio, _ := redis.String(redisCon.Do("HGET", "pool_supplier_ratio", sku.SupplierId))
if ratio == "" { if ratio == "" {
logger.Select("sku_query").Error("系数获取异常,供应商:" + c.ToString(sku.SupplierId)) logger.Select("sku_query").Error("系数获取异常,供应商:" + c.ToString(sku.SupplierId))
...@@ -456,6 +312,7 @@ func (ls *LyService) GetCoefficientAndPrice(sku model.LySku) model.LySku { ...@@ -456,6 +312,7 @@ func (ls *LyService) GetCoefficientAndPrice(sku model.LySku) model.LySku {
if !hasCoefficient { if !hasCoefficient {
coefficient = defaultCoefficient coefficient = defaultCoefficient
} }
//下面是计算价格 //下面是计算价格
//价格计算文档 https://docs.qq.com/doc/DR3RJcnNPeUNkWHRk //价格计算文档 https://docs.qq.com/doc/DR3RJcnNPeUNkWHRk
// 为何是固定的1.13,关税基本不会变,有变的话跟产品沟通手动修改即可 // 为何是固定的1.13,关税基本不会变,有变的话跟产品沟通手动修改即可
...@@ -473,7 +330,7 @@ func (ls *LyService) GetCoefficientAndPrice(sku model.LySku) model.LySku { ...@@ -473,7 +330,7 @@ func (ls *LyService) GetCoefficientAndPrice(sku model.LySku) model.LySku {
continue continue
} }
data[key].Purchases = price.Purchases data[key].Purchases = price.Purchases
//找出对应的阶梯,从$priceRatioList找到对应的售价组系数 //找出对应的阶梯,从priceRatioList找到对应的售价组系数
//这个是为了怕后台存的数据格式不对导致无法获取到对应的系数 //这个是为了怕后台存的数据格式不对导致无法获取到对应的系数
//这里去取对应的售价利润阶梯的时候,是往下匹配的,比如 阶梯价是 1,2,3 售价组利润是 1,2,3,4,5,那么123对应的是售价组利润的345 //这里去取对应的售价利润阶梯的时候,是往下匹配的,比如 阶梯价是 1,2,3 售价组利润是 1,2,3,4,5,那么123对应的是售价组利润的345
//而且当原始阶梯价为10个的时候,超过了售价利润组的9个,就要去取第9个售价利润组 //而且当原始阶梯价为10个的时候,超过了售价利润组的9个,就要去取第9个售价利润组
......
package service package service
import ( import (
"fmt"
"github.com/gomodule/redigo/redis" "github.com/gomodule/redigo/redis"
"github.com/syyongx/php2go" "github.com/syyongx/php2go"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
...@@ -16,57 +17,187 @@ import ( ...@@ -16,57 +17,187 @@ import (
type PriceService struct { type PriceService struct {
} }
// 这里有个前置条件处理美金价,因为element(6)存到美金字段里面的是港币,rs(21)存到美金字段里的是人民币,buerklin(1676)是欧元 // GenerateLadderPrice 构建专营的阶梯价,现在专营只会存一个简单的成本价,阶梯数量是1,所以我这边要根据专营的阶梯系数去构建具体的阶梯价
// 所以要全部先转成正确的美金价才能显示 func (ps *PriceService) GenerateLadderPrice(sku model.LySku) model.LySku {
func (ps *PriceService) TransformSpecialSupplierPrice(supplierId int64, priceUs float64, usRatio float64) float64 { //先去找到对应的价格系数
//去redis获取价格 var ratioDataKey string
redisCon := gredis.Conn("default_r") if sku.Moq <= 50 {
defer func() { ratioDataKey = "cost_ladder_price_egt50_lt200"
redisCon.Close() } else {
}() ratioDataKey = "cost_ladder_price_egt200"
currency, _ := redis.Int(redisCon.Do("HGET", "magic_cube_supplier_currency", supplierId))
if currency > 0 {
//这里进行转换,因为这里都只能取到对应的币种转人民币的比率,我们没有直接各种币种转美金的数据,所以我这边要
//先根据对应币种转人民币,然后根据人民币转美金,才能得到不同币种对应美金的汇率
rmbRatio, _ := redis.Float64(redisCon.Do("HGET", "erp_rate", currency))
//人民币汇率转美金汇率
usRatio = c.MyRound(c.DivFloat(rmbRatio, usRatio), 2)
priceUs = c.MyRound(c.DivFloat(priceUs, usRatio), 4)
} }
return priceUs
}
// 构建专营的阶梯价,现在专营只会存一个简单的成本价,阶梯数量是1,所以我这边要根据专营的阶梯系数去构建具体的阶梯价
func (ps *PriceService) GenerateLadderPrice(sku model.LySku) (generatedLadderPrice []model.LadderPrice, showPriceRatio []model.PriceRatio) {
//先直接获取成本价原始值,判断第一个阶梯的阶梯数量是否为0,如果是0,那么代表是要走成本价生成,如果不是0,那么就要走阶梯价生成
firstLadderPurchases := sku.LadderPrice[0].Purchases
isCostPrice := bool(firstLadderPurchases == 0)
//先去获取配置的redis //先去获取配置的redis
redisCon := gredis.Conn("default_r") redisCon := gredis.Conn("default_r")
defer redisCon.Close() defer redisCon.Close()
priceRatio, _ := redis.String(redisCon.Do("HGET", "magic_cube_price_rule_v2", sku.Canal)) //找一个标志位,因为默认的全局折扣系数的数据格式和非全局的是不一样的
//拿不到就去取默认的 isDefaultPriceRatio := false
if priceRatio == "" { priceRatioCache, _ := redis.String(redisCon.Do("HGET", "magic_cube_price_rule_v2", sku.SupplierId))
priceRatio, _ = redis.String(redisCon.Do("GET", "magic_cube_price_rule_v2_default")) //判断是否是空
checkNullRation := gjson.Get(priceRatioCache, ratioDataKey).String()
//如果这个渠道没有对应的折扣系数,那么就去读取全局的
if priceRatioCache == "" || checkNullRation == "{}" {
isDefaultPriceRatio = true
priceRatioCache, _ = redis.String(redisCon.Do("GET", "magic_cube_price_rule_v2_default"))
}
var priceRatioSort int
//这个就是最终要获取到的价格系数
var priceRatioList []model.PriceRatio
//是否找到系数的标志位
foundRatio := false
//如果只有默认系数,那么就去找默认系数
if isDefaultPriceRatio {
} else {
//拿到系数以后,就要去计算
//拿出里面的所有排序
priceRatioSortMap := gjson.Get(priceRatioCache, ratioDataKey).Map()
var sortNumbers []int
for sortNumberString, _ := range priceRatioSortMap {
sortNumber, _ := strconv.Atoi(sortNumberString)
sortNumbers = append(sortNumbers, sortNumber)
}
//然后确定排序
sortNumbers = sorter.IntSliceSortDesc(sortNumbers)
//确定排序以后,就可以进行按排序(从大到小)取系数
outerLoop:
for _, sortNumber := range sortNumbers {
priceRatioSort = sortNumber
priceRatioList = nil
sortString := strconv.Itoa(sortNumber)
//这个就是找到的系数了
priceRatioArr := gjson.Get(priceRatioCache, ratioDataKey+"."+sortString).Array()
for _, value := range priceRatioArr {
var priceRatio model.PriceRatio
priceRatio.Ratio = gjson.Get(value.String(), "price").Float()
priceRatio.RatioUsd = gjson.Get(value.String(), "price_usd").Float()
priceRatio.Purchases = gjson.Get(value.String(), "purchases").Int()
priceRatioList = append(priceRatioList, priceRatio)
}
//是否满足特定条件的判断
var hasSpecialCheck = false
//判断是否有符合的商品名称
goodsNames := gjson.Get(priceRatioCache, "goods_name."+sortString).String()
if goodsNames != "" {
hasSpecialCheck = true
goodsNameList := strings.Split(goodsNames, "@€@")
//找到有对应的商品名称,那么优先级肯定是最高的了
if php2go.InArray(sku.GoodsName, goodsNameList) {
foundRatio = true
break
}
}
//判断是否有符合的标准品牌ID
brandIds := gjson.Get(priceRatioCache, "brand."+sortString).String()
if brandIds != "" {
hasSpecialCheck = true
standardBrandIdList := strings.Split(brandIds, ",")
standardBrandId := strconv.Itoa(sku.StandardBrand.StandardBrandId)
//找到有对应的品牌,那么优先级肯定是最高的了
if php2go.InArray(standardBrandId, standardBrandIdList) {
foundRatio = true
break
}
}
//判断是否有符合的eccn
eccns := gjson.Get(priceRatioCache, "eccn."+sortString).String()
if eccns != "" {
hasSpecialCheck = true
eccnList := strings.Split(eccns, ",")
//找到有对应的eccn,那么优先级肯定是最高的了
for _, eccn := range eccnList {
//判断是否有百分号匹配
//如果是纯%,那就是不对的,要跳过
if strings.Replace(eccn, "%", "", 10) == "" {
continue
}
if strings.Contains(eccn, "%") {
hasPrefix := strings.HasPrefix(eccn, "%")
hasSuffix := strings.HasSuffix(eccn, "%")
if hasPrefix && hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10)
if strings.Contains(sku.Eccn, eccn) {
foundRatio = true
break outerLoop
}
}
if hasPrefix && !hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10)
if strings.HasSuffix(sku.Eccn, eccn) {
foundRatio = true
break outerLoop
}
}
if !hasPrefix && hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10)
if strings.HasPrefix(sku.Eccn, eccn) {
foundRatio = true
break outerLoop
}
}
} else {
if sku.Eccn == eccn {
foundRatio = true
break outerLoop
}
}
}
}
//如果没有设置品牌和商品,那么这个优先级高的就会覆盖下面的了,不需要再去判断品牌和型号了
if hasSpecialCheck {
continue
}
foundRatio = true
break
}
}
//找不到特定的系数,那就去找全局的
if !foundRatio {
priceRatioCache, _ = redis.String(redisCon.Do("GET", "magic_cube_price_rule_v2_default"))
priceRatioArr := gjson.Get(priceRatioCache, ratioDataKey).Array()
priceRatioList = nil
for _, value := range priceRatioArr {
var priceRatio model.PriceRatio
priceRatio.Ratio = gjson.Get(value.String(), "ratio").Float()
priceRatio.RatioUsd = gjson.Get(value.String(), "ratio_usd").Float()
priceRatioList = append(priceRatioList, priceRatio)
}
priceRatioSort = -1
} }
sku.PriceRatio = priceRatioList
sku.PriceRatioSort = priceRatioSort
//这是用来展示在商品服务的价格系数,专营的系数和代购的不一样,所以要转换一下展示形式 //这是用来展示在商品服务的价格系数,专营的系数和代购的不一样,所以要转换一下展示形式
//是否有设置最低利润点阶梯,不足5个阶梯时,最高阶梯对应的最小利润点阶梯 //是否有设置最低利润点阶梯,不足5个阶梯时,最高阶梯对应的最小利润点阶梯
ladderPriceMiniProfitLevel := int(gjson.Get(priceRatio, "ladder_price_mini_profit_level").Int()) var ladderPriceMiniProfitLevel int
fmt.Println("是否找到系数", foundRatio)
fmt.Println("系数redis数据为 : ", priceRatioCache)
fmt.Println("具体系数为 : ", priceRatioList)
if foundRatio {
priceRatioSortStr := strconv.Itoa(priceRatioSort)
ladderPriceMiniProfitLevel = int(gjson.Get(priceRatioCache, "ladder_price_mini_profit_level."+priceRatioSortStr).Int())
} else {
ladderPriceMiniProfitLevel = int(gjson.Get(priceRatioCache, "ladder_price_mini_profit_level").Int())
}
fmt.Println("最低利润点阶梯数 : ", ladderPriceMiniProfitLevel)
var generatedLadderPrice []model.LadderPrice
//先直接获取成本价原始值,判断第一个阶梯的阶梯数量是否为0,如果是0,那么代表是要走成本价生成,如果不是0,那么就要走阶梯价生成
firstLadderPurchases := sku.LadderPrice[0].Purchases
isCostPrice := bool(firstLadderPurchases == 0)
//判断是否走成本价判断还是走阶梯价判断,因为上传sku的时候,可以设置每个sku的成本价(人民币&&美金),也可以设置每个sku的阶梯价 //判断是否走成本价判断还是走阶梯价判断,因为上传sku的时候,可以设置每个sku的成本价(人民币&&美金),也可以设置每个sku的阶梯价
//如果有阶梯价,就要跳过设置的成本价(假设有设置的话) //如果有阶梯价,就要跳过设置的成本价(假设有设置的话)
if isCostPrice { if isCostPrice {
costPriceCn := sku.LadderPrice[0].PriceCn costPriceCn := sku.LadderPrice[0].PriceCn
costPriceUs := sku.LadderPrice[0].PriceUs costPriceUs := sku.LadderPrice[0].PriceUs
//fmt.Println("人民币和美金的成本价分别为 : ", costPriceCn, costPriceUs) //fmt.Println("人民币和美金的成本价分别为 : ", costPriceCn, costPriceUs)
//先去判断起订量,如果起订量小于50,就要走固定配置的阶梯价格系数 //先去判断起订量,如果起订量小于50,就要走固定配置的阶梯系数
if sku.Moq <= 50 { if sku.Moq <= 50 {
moq := int(sku.Moq) moq := int(sku.Moq)
fixedRatio := make(map[int]float64) fixedRatio := make(map[int]float64)
//当起订量是小于等于50的时候,阶梯数量和阶梯数是固定的,但是具体的利润还是要去取配置的值,因为固定死的阶梯数量是5,所以这边要直接取魔方配置9个的后5个 //当起订量是小于等于50的时候,阶梯数量和阶梯数是固定的,但是具体的利润还是要去取配置的值,因为固定死的阶梯数量是5,所以这边要直接取魔方配置9个的后5个
costLadderPriceRatio := gjson.Get(priceRatio, "cost_ladder_price_egt50_lt200").Map() if len(priceRatioList) == 9 {
if len(costLadderPriceRatio) == 9 { //priceRatioAndPurchases := priceRatioList[strconv.Itoa(i)]
//priceRatioAndPurchases := costLadderPriceRatio[strconv.Itoa(i)]
//priceCnRatio := priceRatioAndPurchases.Get("price").Float() //priceCnRatio := priceRatioAndPurchases.Get("price").Float()
var fixedPurchases []int var fixedPurchases []int
switch { switch {
...@@ -81,11 +212,10 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) (generatedLadderPri ...@@ -81,11 +212,10 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) (generatedLadderPri
break break
} }
for index, purchase := range fixedPurchases { for index, purchase := range fixedPurchases {
//costLadderPriceRatio这个redis是字典,下标从1开始的,所以要从第5个开始取 //costLadderPriceRatio这个redis是字典,下标从0开始的,所以要从第5个开始取
ratio := costLadderPriceRatio[strconv.Itoa(5+index)].Get("price").Float() ratio := priceRatioList[4+index].Ratio
ratioUsd := costLadderPriceRatio[strconv.Itoa(5+index)].Get("price_usd").Float() ratioUsd := priceRatioList[4+index].RatioUsd
//同时还要构建价格系数展示在商品服务 //同时还要构建价格系数展示在商品服务
showPriceRatio = append(showPriceRatio, model.PriceRatio{Ratio: ratio, RatioUsd: ratioUsd})
generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{ generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{
Purchases: int64(purchase), Purchases: int64(purchase),
PriceCn: c.MyRound(c.MulFloat(costPriceCn, ratio), 4), PriceCn: c.MyRound(c.MulFloat(costPriceCn, ratio), 4),
...@@ -110,7 +240,6 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) (generatedLadderPri ...@@ -110,7 +240,6 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) (generatedLadderPri
//然后根据一开始只有一个的阶梯价去生成阶梯价格 //然后根据一开始只有一个的阶梯价去生成阶梯价格
for purchases, ratio := range fixedRatio { for purchases, ratio := range fixedRatio {
//同时还要构建价格系数展示在商品服务 //同时还要构建价格系数展示在商品服务
showPriceRatio = append(showPriceRatio, model.PriceRatio{Ratio: ratio, RatioUsd: ratio})
generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{ generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{
Purchases: int64(purchases), Purchases: int64(purchases),
PriceCn: c.MyRound(c.MulFloat(costPriceCn, ratio), 4), PriceCn: c.MyRound(c.MulFloat(costPriceCn, ratio), 4),
...@@ -119,40 +248,29 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) (generatedLadderPri ...@@ -119,40 +248,29 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) (generatedLadderPri
} }
} }
sort.Slice(showPriceRatio, func(i, j int) bool {
return showPriceRatio[i].Ratio > showPriceRatio[j].Ratio
})
sku.PriceRatio = showPriceRatio
sort.Slice(generatedLadderPrice, func(i, j int) bool { sort.Slice(generatedLadderPrice, func(i, j int) bool {
return generatedLadderPrice[i].Purchases < generatedLadderPrice[j].Purchases return generatedLadderPrice[i].Purchases < generatedLadderPrice[j].Purchases
}) })
return generatedLadderPrice, showPriceRatio sku.LadderPrice = generatedLadderPrice
return sku
} }
//判断最小起订量是属于哪个范围 fmt.Println("是成本价")
ratioKey := ""
if sku.Moq >= 50 && sku.Moq < 200 {
ratioKey = "cost_ladder_price_egt50_lt200"
} else {
ratioKey = "cost_ladder_price_egt200"
}
costLadderPriceRatio := gjson.Get(priceRatio, ratioKey).Map()
// 成本价阶梯数 由最高库存计算得到 // 成本价阶梯数 由最高库存计算得到
costLadderCount := 0 costLadderCount := 0
for i := 1; i <= len(costLadderPriceRatio); i++ { for i := 0; i < len(priceRatioList); i++ {
costPurchases := costLadderPriceRatio[strconv.Itoa(i)].Get("purchases").Int() costPurchases := priceRatioList[i].Purchases
if costPurchases*sku.Moq > sku.Stock { if costPurchases*sku.Moq > sku.Stock {
break break
} }
costLadderCount++ costLadderCount++
} }
//fmt.Println("阶梯数量为 : ", costLadderCount) fmt.Println("阶梯数量为 : ", costLadderCount)
//fmt.Println("设置的利润阶梯为 : ", ladderPriceMiniProfitLevel) fmt.Println("设置的利润阶梯为 : ", ladderPriceMiniProfitLevel)
if costLadderCount <= ladderPriceMiniProfitLevel { if costLadderCount <= ladderPriceMiniProfitLevel {
for i := 1; i <= costLadderCount; i++ { for i := 0; i < costLadderCount; i++ {
priceRatioAndPurchases := costLadderPriceRatio[strconv.Itoa(i)] priceRatioAndPurchases := priceRatioList[i]
// 阶梯数量系数正序取 // 阶梯数量系数正序取
costPurchases := sku.Moq * priceRatioAndPurchases.Get("purchases").Int() costPurchases := sku.Moq * priceRatioAndPurchases.Purchases
//fmt.Println(costPurchases, sku.Stock) //fmt.Println(costPurchases, sku.Stock)
// 阶梯数量上限为库存量,超出则不再计算下级阶梯 // 阶梯数量上限为库存量,超出则不再计算下级阶梯
if costPurchases > sku.Stock { if costPurchases > sku.Stock {
...@@ -166,63 +284,58 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) (generatedLadderPri ...@@ -166,63 +284,58 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) (generatedLadderPri
if costMapIndex <= 0 { if costMapIndex <= 0 {
costMapIndex = 1 costMapIndex = 1
} }
priceRatioAndPurchases = costLadderPriceRatio[strconv.Itoa(costMapIndex)] priceRatioAndPurchases = priceRatioList[costMapIndex]
//fmt.Println("获取到的阶梯系数为 : ", priceRatioAndPurchases) //fmt.Println("获取到的阶梯系数为 : ", priceRatioAndPurchases)
priceCnRatio := priceRatioAndPurchases.Get("price").Float() priceCnRatio := priceRatioAndPurchases.Ratio
priceUsRatio := priceRatioAndPurchases.Get("price_usd").Float() priceUsRatio := priceRatioAndPurchases.RatioUsd
// 阶梯价格系数正序取 // 阶梯价格系数正序取
showPriceRatio = append(showPriceRatio, model.PriceRatio{Ratio: priceCnRatio, RatioUsd: priceUsRatio})
generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{ generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{
Purchases: costPurchases, Purchases: costPurchases,
PriceCn: c.MyRound(c.MulFloat(costPriceCn, priceCnRatio), 4), PriceCn: c.MyRound(c.MulFloat(costPriceCn, priceCnRatio), 4),
PriceUs: c.MyRound(c.MulFloat(costPriceUs, priceUsRatio), 4), PriceUs: c.MyRound(c.MulFloat(costPriceUs, priceUsRatio), 4),
}) })
sku.PriceRatio = showPriceRatio
} }
} else { } else {
//价格阶梯数量超过最利润点的层级的情况 //价格阶梯数量超过最利润点的层级的情况
for i := 1; i <= costLadderCount; i++ { for i := 0; i < costLadderCount; i++ {
priceRatioAndPurchases := costLadderPriceRatio[strconv.Itoa(i)] priceRatioAndPurchases := priceRatioList[i]
// 阶梯数量系数正序取 // 阶梯数量系数正序取
costPurchases := sku.Moq * priceRatioAndPurchases.Get("purchases").Int() costPurchases := sku.Moq * priceRatioAndPurchases.Purchases
// 阶梯数量上限为库存量,超出则不再计算下级阶梯 // 阶梯数量上限为库存量,超出则不再计算下级阶梯
if costPurchases > sku.Stock { if costPurchases > sku.Stock {
break break
} }
priceCnRatio := priceRatioAndPurchases.Get("price").Float() priceCnRatio := priceRatioAndPurchases.Ratio
priceUsRatio := priceRatioAndPurchases.Get("price_usd").Float() priceUsRatio := priceRatioAndPurchases.RatioUsd
showPriceRatio = append(showPriceRatio, model.PriceRatio{Ratio: priceCnRatio, RatioUsd: priceUsRatio})
// 阶梯价格系数正序取 // 阶梯价格系数正序取
generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{ generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{
Purchases: sku.Moq * priceRatioAndPurchases.Get("purchases").Int(), Purchases: sku.Moq * priceRatioAndPurchases.Purchases,
PriceCn: c.MyRound(c.MulFloat(costPriceCn, priceCnRatio), 4), PriceCn: c.MyRound(c.MulFloat(costPriceCn, priceCnRatio), 4),
PriceUs: c.MyRound(c.MulFloat(costPriceUs, priceUsRatio), 4), PriceUs: c.MyRound(c.MulFloat(costPriceUs, priceUsRatio), 4),
}) })
} }
sku.PriceRatio = showPriceRatio
} }
return generatedLadderPrice, showPriceRatio sku.LadderPrice = generatedLadderPrice
return sku
} else { } else {
ladderPriceRatio := gjson.Get(priceRatio, "ladder_price_egt50_lt200").Map()
//fmt.Println(ladderPriceRatio) //fmt.Println(ladderPriceRatio)
ladderCount := len(sku.LadderPrice) ladderCount := len(sku.LadderPrice)
//走阶梯价 //走阶梯价
if ladderCount <= ladderPriceMiniProfitLevel { if ladderCount <= ladderPriceMiniProfitLevel {
for i := 1; i <= ladderCount; i++ { for i := 0; i < ladderCount; i++ {
ladder := sku.LadderPrice[i-1] ladder := sku.LadderPrice[i]
//利润阶梯索引 //利润阶梯索引
//计算出库存满足了n个价格阶梯之后 从最小利润点层级反向取n个层级,然后正序计算 如:库存满足1、2、3层阶梯,最小利润点层级是第5个层级,则利润点取3、4、5层级的 //计算出库存满足了n个价格阶梯之后 从最小利润点层级反向取n个层级,然后正序计算 如:库存满足1、2、3层阶梯,最小利润点层级是第5个层级,则利润点取3、4、5层级的
//最小利润点层级 - 库存满足多少个阶梯 + i //最小利润点层级 - 库存满足多少个阶梯 + i
costMapIndex := ladderPriceMiniProfitLevel - ladderCount + i costMapIndex := ladderPriceMiniProfitLevel - ladderCount + i
if costMapIndex <= 0 { if costMapIndex <= 0 {
costMapIndex = 1 costMapIndex = 0
} }
//fmt.Println(costMapIndex) //fmt.Println(costMapIndex)
priceRatio := ladderPriceRatio[strconv.Itoa(costMapIndex)] priceRatio := priceRatioList[costMapIndex]
//fmt.Println("获取到的阶梯系数为 : ", priceRatio) //fmt.Println("获取到的阶梯系数为 : ", priceRatio)
priceCnRatio := priceRatio.Get("ratio").Float() priceCnRatio := priceRatio.Ratio
priceUsRatio := priceRatio.Get("ratio_usd").Float() priceUsRatio := priceRatio.RatioUsd
showPriceRatio = append(showPriceRatio, model.PriceRatio{Ratio: priceCnRatio, RatioUsd: priceUsRatio})
// 阶梯价格系数正序取 // 阶梯价格系数正序取
generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{ generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{
Purchases: ladder.Purchases, Purchases: ladder.Purchases,
...@@ -230,31 +343,29 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) (generatedLadderPri ...@@ -230,31 +343,29 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) (generatedLadderPri
PriceUs: c.MyRound(c.MulFloat(ladder.PriceUs, priceUsRatio), 4), PriceUs: c.MyRound(c.MulFloat(ladder.PriceUs, priceUsRatio), 4),
}) })
} }
sku.PriceRatio = showPriceRatio
} else { } else {
//价格阶梯数量超过最利润点的层级的情况 //价格阶梯数量超过最利润点的层级的情况
for i := 1; i <= 9; i++ { for i := 0; i < 9; i++ {
ladder := sku.LadderPrice[i-1] ladder := sku.LadderPrice[i]
// 阶梯数量系数正序取 // 阶梯数量系数正序取
priceRatio := ladderPriceRatio[strconv.Itoa(i)] priceRatio := priceRatioList[i]
priceCnRatio := priceRatio.Get("ratio").Float() priceCnRatio := priceRatio.Ratio
priceUsRatio := priceRatio.Get("ratio_usd").Float() priceUsRatio := priceRatio.RatioUsd
showPriceRatio = append(showPriceRatio, model.PriceRatio{Ratio: priceCnRatio, RatioUsd: priceUsRatio})
// 阶梯价格系数正序取 // 阶梯价格系数正序取
generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{ generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{
Purchases: int64(ladder.Purchases), Purchases: int64(ladder.Purchases),
PriceCn: c.MyRound(c.MulFloat(ladder.PriceCn, priceRatio.Get("ratio").Float()), 4), PriceCn: c.MyRound(c.MulFloat(ladder.PriceCn, priceCnRatio), 4),
PriceUs: c.MyRound(c.MulFloat(ladder.PriceUs, priceRatio.Get("ratio_usd").Float()), 4), PriceUs: c.MyRound(c.MulFloat(ladder.PriceUs, priceUsRatio), 4),
}) })
} }
sku.PriceRatio = showPriceRatio
} }
return generatedLadderPrice, showPriceRatio sku.LadderPrice = generatedLadderPrice
return sku
} }
} }
// 获取折扣系数 // 获取折扣系数(通用)
func (ps *PriceService) GetDiscountRatio(sku model.LySku) model.LySku { func (ps *PriceService) GetDiscountRatio(sku model.LySku) model.LySku {
redisCon := gredis.Conn("default_r") redisCon := gredis.Conn("default_r")
defer redisCon.Close() defer redisCon.Close()
...@@ -342,3 +453,167 @@ func (ps *PriceService) GetDiscountRatio(sku model.LySku) model.LySku { ...@@ -342,3 +453,167 @@ func (ps *PriceService) GetDiscountRatio(sku model.LySku) model.LySku {
return sku return sku
} }
// 获取售价组(代购)
func (ps PriceService) GetPriceRatio(sku model.LySku) (model.LySku, []model.PriceRatio) {
redisCon := gredis.Conn("default_r")
defer redisCon.Close()
//找一个标志位,因为默认的全局折扣系数的数据格式和非全局的是不一样的
isDefaultPriceRatio := false
priceRatioCache, _ := redis.String(redisCon.Do("HGET", "magic_cube_price_rule_channel", sku.SupplierId))
checkNullRation := gjson.Get(priceRatioCache, "ladder_price").String()
//如果这个渠道没有对应的折扣系数,那么就去读取全局的
if priceRatioCache == "" || checkNullRation == "{}" {
isDefaultPriceRatio = true
priceRatioCache, _ = redis.String(redisCon.Do("GET", "magic_cube_price_rule_channel_default"))
}
var priceRatioSort int
//这个就是最终要获取到的价格系数
var priceRatioList []model.PriceRatio
//是否找到系数的标志位
foundRatio := false
//如果只有默认系数,那么就去找默认系数
if isDefaultPriceRatio {
} else {
//拿到系数以后,就要去计算
//拿出里面的所有排序
priceRatioSortMap := gjson.Get(priceRatioCache, "ladder_price").Map()
var sortNumbers []int
for sortNumberString, _ := range priceRatioSortMap {
sortNumber, _ := strconv.Atoi(sortNumberString)
sortNumbers = append(sortNumbers, sortNumber)
}
//然后确定排序
sortNumbers = sorter.IntSliceSortDesc(sortNumbers)
//确定排序以后,就可以进行按排序(从大到小)取系数
outerLoop:
for _, sortNumber := range sortNumbers {
priceRatioSort = sortNumber
priceRatioList = nil
sortString := strconv.Itoa(sortNumber)
priceRatioArr := gjson.Get(priceRatioCache, "ladder_price."+sortString).Array()
for _, value := range priceRatioArr {
var priceRatio model.PriceRatio
priceRatio.Ratio = gjson.Get(value.String(), "ratio").Float()
priceRatio.RatioUsd = gjson.Get(value.String(), "ratio_usd").Float()
priceRatioList = append(priceRatioList, priceRatio)
}
var hasSpecialCheck = false
//判断是否有符合的商品名称
goodsNames := gjson.Get(priceRatioCache, "goods_name."+sortString).String()
if goodsNames != "" {
hasSpecialCheck = true
goodsNameList := strings.Split(goodsNames, "@€@")
//找到有对应的商品名称,那么优先级肯定是最高的了
if php2go.InArray(sku.GoodsName, goodsNameList) {
foundRatio = true
break
}
}
//判断是否有符合的标准品牌ID
brandIds := gjson.Get(priceRatioCache, "brand."+sortString).String()
if brandIds != "" {
hasSpecialCheck = true
standardBrandIdList := strings.Split(brandIds, ",")
standardBrandId := strconv.Itoa(sku.StandardBrand.StandardBrandId)
//找到有对应的品牌,那么优先级肯定是最高的了
if php2go.InArray(standardBrandId, standardBrandIdList) {
foundRatio = true
break
}
}
//判断是否有符合的eccn
eccns := gjson.Get(priceRatioCache, "eccn."+sortString).String()
if eccns != "" {
hasSpecialCheck = true
eccnList := strings.Split(eccns, ",")
//找到有对应的eccn,那么优先级肯定是最高的了
for _, eccn := range eccnList {
//判断是否有百分号匹配
//如果是纯%,那就是不对的,要跳过
if strings.Replace(eccn, "%", "", 10) == "" {
continue
}
if strings.Contains(eccn, "%") {
hasPrefix := strings.HasPrefix(eccn, "%")
hasSuffix := strings.HasSuffix(eccn, "%")
if hasPrefix && hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10)
if strings.Contains(sku.Eccn, eccn) {
foundRatio = true
break outerLoop
}
}
if hasPrefix && !hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10)
if strings.HasSuffix(sku.Eccn, eccn) {
foundRatio = true
break outerLoop
}
}
if !hasPrefix && hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10)
if strings.HasPrefix(sku.Eccn, eccn) {
foundRatio = true
break outerLoop
}
}
} else {
if sku.Eccn == eccn {
foundRatio = true
break outerLoop
}
}
}
}
//如果没有设置品牌和商品,那么这个优先级高的就会覆盖下面的了,不需要再去判断品牌和型号了
if hasSpecialCheck {
continue
}
foundRatio = true
break
}
}
//找不到特定的系数,那就去找全局的
if !foundRatio {
priceRatioCache, _ = redis.String(redisCon.Do("GET", "magic_cube_price_rule_channel_default"))
priceRatioArr := gjson.Get(priceRatioCache, "ladder_price").Array()
priceRatioList = nil
for _, value := range priceRatioArr {
var priceRatio model.PriceRatio
priceRatio.Ratio = gjson.Get(value.String(), "ratio").Float()
priceRatio.RatioUsd = gjson.Get(value.String(), "ratio_usd").Float()
priceRatioList = append(priceRatioList, priceRatio)
}
priceRatioSort = -1
}
sku.PriceRatio = priceRatioList
sku.PriceRatioSort = priceRatioSort
return sku, priceRatioList
}
// TransformSpecialSupplierPrice 这里有个前置条件处理美金价,因为element(6)存到美金字段里面的是港币,rs(21)存到美金字段里的是人民币,buerklin(1676)是欧元
// 所以要全部先转成正确的美金价才能显示
func (ps *PriceService) TransformSpecialSupplierPrice(supplierId int64, priceUs float64, usRatio float64) float64 {
//去redis获取价格
redisCon := gredis.Conn("default_r")
defer func() {
redisCon.Close()
}()
currency, _ := redis.Int(redisCon.Do("HGET", "magic_cube_supplier_currency", supplierId))
if currency > 0 {
//这里进行转换,因为这里都只能取到对应的币种转人民币的比率,我们没有直接各种币种转美金的数据,所以我这边要
//先根据对应币种转人民币,然后根据人民币转美金,才能得到不同币种对应美金的汇率
rmbRatio, _ := redis.Float64(redisCon.Do("HGET", "erp_rate", currency))
//人民币汇率转美金汇率
usRatio = c.MyRound(c.DivFloat(rmbRatio, usRatio), 2)
priceUs = c.MyRound(c.DivFloat(priceUs, usRatio), 4)
}
return priceUs
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment