Fix product performance grouped JSON build
This commit is contained in:
@@ -4676,21 +4676,21 @@ FROM (
|
|||||||
CASE WHEN SUM(sales_qty_90d) > 0 THEN SUM(margin_index_90d * sales_qty_90d) / NULLIF(SUM(sales_qty_90d),0) ELSE 0 END AS margin_index_90d,
|
CASE WHEN SUM(sales_qty_90d) > 0 THEN SUM(margin_index_90d * sales_qty_90d) / NULLIF(SUM(sales_qty_90d),0) ELSE 0 END AS margin_index_90d,
|
||||||
CASE
|
CASE
|
||||||
WHEN SUM(CASE
|
WHEN SUM(CASE
|
||||||
WHEN COALESCE(sales_usd_90d,0) > 0 THEN sales_usd_90d
|
|
||||||
WHEN COALESCE(sales_qty_90d,0) > 0 THEN sales_qty_90d
|
WHEN COALESCE(sales_qty_90d,0) > 0 THEN sales_qty_90d
|
||||||
|
WHEN COALESCE(sales_usd_90d,0) > 0 THEN sales_usd_90d
|
||||||
WHEN COALESCE(stock_qty,0) > 0 AND COALESCE(cost_price_usd,0) > 0 THEN stock_qty * cost_price_usd
|
WHEN COALESCE(stock_qty,0) > 0 AND COALESCE(cost_price_usd,0) > 0 THEN stock_qty * cost_price_usd
|
||||||
WHEN COALESCE(stock_qty,0) > 0 THEN stock_qty
|
WHEN COALESCE(stock_qty,0) > 0 THEN stock_qty
|
||||||
ELSE 1
|
ELSE 1
|
||||||
END) > 0
|
END) > 0
|
||||||
THEN SUM(performance_score * CASE
|
THEN SUM(performance_score * CASE
|
||||||
WHEN COALESCE(sales_usd_90d,0) > 0 THEN sales_usd_90d
|
|
||||||
WHEN COALESCE(sales_qty_90d,0) > 0 THEN sales_qty_90d
|
WHEN COALESCE(sales_qty_90d,0) > 0 THEN sales_qty_90d
|
||||||
|
WHEN COALESCE(sales_usd_90d,0) > 0 THEN sales_usd_90d
|
||||||
WHEN COALESCE(stock_qty,0) > 0 AND COALESCE(cost_price_usd,0) > 0 THEN stock_qty * cost_price_usd
|
WHEN COALESCE(stock_qty,0) > 0 AND COALESCE(cost_price_usd,0) > 0 THEN stock_qty * cost_price_usd
|
||||||
WHEN COALESCE(stock_qty,0) > 0 THEN stock_qty
|
WHEN COALESCE(stock_qty,0) > 0 THEN stock_qty
|
||||||
ELSE 1
|
ELSE 1
|
||||||
END) / NULLIF(SUM(CASE
|
END) / NULLIF(SUM(CASE
|
||||||
WHEN COALESCE(sales_usd_90d,0) > 0 THEN sales_usd_90d
|
|
||||||
WHEN COALESCE(sales_qty_90d,0) > 0 THEN sales_qty_90d
|
WHEN COALESCE(sales_qty_90d,0) > 0 THEN sales_qty_90d
|
||||||
|
WHEN COALESCE(sales_usd_90d,0) > 0 THEN sales_usd_90d
|
||||||
WHEN COALESCE(stock_qty,0) > 0 AND COALESCE(cost_price_usd,0) > 0 THEN stock_qty * cost_price_usd
|
WHEN COALESCE(stock_qty,0) > 0 AND COALESCE(cost_price_usd,0) > 0 THEN stock_qty * cost_price_usd
|
||||||
WHEN COALESCE(stock_qty,0) > 0 THEN stock_qty
|
WHEN COALESCE(stock_qty,0) > 0 THEN stock_qty
|
||||||
ELSE 1
|
ELSE 1
|
||||||
@@ -6051,10 +6051,19 @@ func productPerformanceMapVariantKey(row map[string]any) string {
|
|||||||
func deriveProductPerformanceGroupMetrics(out map[string]any, groupField string) {
|
func deriveProductPerformanceGroupMetrics(out map[string]any, groupField string) {
|
||||||
normalizeProductPerformanceCostFields(out)
|
normalizeProductPerformanceCostFields(out)
|
||||||
preservedCustomerScores := map[string]float64{}
|
preservedCustomerScores := map[string]float64{}
|
||||||
|
preservedProductScores := map[string]float64{}
|
||||||
for _, suffix := range productPerformancePeriodSuffixes() {
|
for _, suffix := range productPerformancePeriodSuffixes() {
|
||||||
if score, ok := productPerformanceOptionalFloat(out, "customer_score_"+suffix); ok {
|
if score, ok := productPerformanceOptionalFloat(out, "customer_score_"+suffix); ok {
|
||||||
preservedCustomerScores[suffix] = score
|
preservedCustomerScores[suffix] = score
|
||||||
}
|
}
|
||||||
|
if score, ok := productPerformanceOptionalFloat(out, "performance_score_"+suffix); ok {
|
||||||
|
preservedProductScores[suffix] = score
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if score, ok := productPerformanceOptionalFloat(out, "performance_score"); ok {
|
||||||
|
if _, exists := preservedProductScores["90d"]; !exists {
|
||||||
|
preservedProductScores["90d"] = score
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for _, suffix := range productPerformancePeriodSuffixes() {
|
for _, suffix := range productPerformancePeriodSuffixes() {
|
||||||
sales := floatFromMap(out, "sales_usd_"+suffix)
|
sales := floatFromMap(out, "sales_usd_"+suffix)
|
||||||
@@ -6135,8 +6144,12 @@ func deriveProductPerformanceGroupMetrics(out map[string]any, groupField string)
|
|||||||
} else {
|
} else {
|
||||||
out["customer_score_"+suffix] = productPerformanceCustomerSalesPeriodScore(rowPeriodMetricMap(out, suffix))
|
out["customer_score_"+suffix] = productPerformanceCustomerSalesPeriodScore(rowPeriodMetricMap(out, suffix))
|
||||||
}
|
}
|
||||||
|
if score, ok := preservedProductScores[suffix]; ok {
|
||||||
|
out["performance_score_"+suffix] = score
|
||||||
|
} else {
|
||||||
out["performance_score_"+suffix] = productPerformanceSalesPeriodScore(out, suffix)
|
out["performance_score_"+suffix] = productPerformanceSalesPeriodScore(out, suffix)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
out["performance_score"] = out["performance_score_90d"]
|
out["performance_score"] = out["performance_score_90d"]
|
||||||
if floatFromMap(out, "order_qty") > 0 || floatFromMap(out, "order_usd") > 0 {
|
if floatFromMap(out, "order_qty") > 0 || floatFromMap(out, "order_usd") > 0 {
|
||||||
score := productPerformanceOrderGroupScore(out)
|
score := productPerformanceOrderGroupScore(out)
|
||||||
@@ -6737,10 +6750,10 @@ func productPerformanceScoreSuffix(field string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func productPerformanceScoreWeight(row map[string]any, suffix string) float64 {
|
func productPerformanceScoreWeight(row map[string]any, suffix string) float64 {
|
||||||
if weight := floatFromMap(row, "sales_usd_"+suffix); weight > 0 {
|
if weight := floatFromMap(row, "sales_qty_"+suffix); weight > 0 {
|
||||||
return weight
|
return weight
|
||||||
}
|
}
|
||||||
if weight := floatFromMap(row, "sales_qty_"+suffix); weight > 0 {
|
if weight := floatFromMap(row, "sales_usd_"+suffix); weight > 0 {
|
||||||
return weight
|
return weight
|
||||||
}
|
}
|
||||||
stockQty := floatFromMap(row, "stock_qty")
|
stockQty := floatFromMap(row, "stock_qty")
|
||||||
|
|||||||
@@ -3536,10 +3536,20 @@ function weightFieldForMetric (field) {
|
|||||||
function applyDerivedGroupMetrics (out, sourceRows, groupField = '') {
|
function applyDerivedGroupMetrics (out, sourceRows, groupField = '') {
|
||||||
Object.assign(out, normalizeProductCostFields(out))
|
Object.assign(out, normalizeProductCostFields(out))
|
||||||
const preservedCustomerScores = {}
|
const preservedCustomerScores = {}
|
||||||
|
const preservedProductScores = {}
|
||||||
for (const suffix of ['90d', '180d', '365d', 'total']) {
|
for (const suffix of ['90d', '180d', '365d', 'total']) {
|
||||||
if (Object.prototype.hasOwnProperty.call(out, `customer_score_${suffix}`)) {
|
if (Object.prototype.hasOwnProperty.call(out, `customer_score_${suffix}`)) {
|
||||||
preservedCustomerScores[suffix] = Number(out[`customer_score_${suffix}`] || 0)
|
preservedCustomerScores[suffix] = Number(out[`customer_score_${suffix}`] || 0)
|
||||||
}
|
}
|
||||||
|
if (Object.prototype.hasOwnProperty.call(out, `performance_score_${suffix}`)) {
|
||||||
|
preservedProductScores[suffix] = Number(out[`performance_score_${suffix}`] || 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
Object.prototype.hasOwnProperty.call(out, 'performance_score') &&
|
||||||
|
!Object.prototype.hasOwnProperty.call(preservedProductScores, '90d')
|
||||||
|
) {
|
||||||
|
preservedProductScores['90d'] = Number(out.performance_score || 0)
|
||||||
}
|
}
|
||||||
for (const suffix of ['90d', '180d', '365d', 'total']) {
|
for (const suffix of ['90d', '180d', '365d', 'total']) {
|
||||||
const sales = Number(out[`sales_usd_${suffix}`] || 0)
|
const sales = Number(out[`sales_usd_${suffix}`] || 0)
|
||||||
@@ -3596,7 +3606,9 @@ function applyDerivedGroupMetrics (out, sourceRows, groupField = '') {
|
|||||||
out[`customer_score_${suffix}`] = Object.prototype.hasOwnProperty.call(preservedCustomerScores, suffix)
|
out[`customer_score_${suffix}`] = Object.prototype.hasOwnProperty.call(preservedCustomerScores, suffix)
|
||||||
? preservedCustomerScores[suffix]
|
? preservedCustomerScores[suffix]
|
||||||
: customerSalesPeriodScore(periodMetricSource(out, suffix))
|
: customerSalesPeriodScore(periodMetricSource(out, suffix))
|
||||||
out[`performance_score_${suffix}`] = productSalesPeriodScore(productPeriodMetricSource(out, suffix))
|
out[`performance_score_${suffix}`] = Object.prototype.hasOwnProperty.call(preservedProductScores, suffix)
|
||||||
|
? preservedProductScores[suffix]
|
||||||
|
: productSalesPeriodScore(productPeriodMetricSource(out, suffix))
|
||||||
}
|
}
|
||||||
out.performance_score = Number(out.performance_score_90d || 0)
|
out.performance_score = Number(out.performance_score_90d || 0)
|
||||||
}
|
}
|
||||||
@@ -3997,10 +4009,10 @@ function scoreSuffixForMetric (field) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function scoreWeight (row, suffix) {
|
function scoreWeight (row, suffix) {
|
||||||
const salesUsd = Number(row?.[`sales_usd_${suffix}`] || 0)
|
|
||||||
if (salesUsd > 0) return salesUsd
|
|
||||||
const salesQty = Number(row?.[`sales_qty_${suffix}`] || 0)
|
const salesQty = Number(row?.[`sales_qty_${suffix}`] || 0)
|
||||||
if (salesQty > 0) return salesQty
|
if (salesQty > 0) return salesQty
|
||||||
|
const salesUsd = Number(row?.[`sales_usd_${suffix}`] || 0)
|
||||||
|
if (salesUsd > 0) return salesUsd
|
||||||
const stockQty = Number(row?.stock_qty || 0)
|
const stockQty = Number(row?.stock_qty || 0)
|
||||||
if (stockQty <= 0) return 1
|
if (stockQty <= 0) return 1
|
||||||
const costPrice = Number(row?.[`cost_price_usd_${suffix}`] || row?.cost_price_usd || 0)
|
const costPrice = Number(row?.[`cost_price_usd_${suffix}`] || row?.cost_price_usd || 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user