Fix product performance grouped JSON build
This commit is contained in:
@@ -4677,25 +4677,16 @@ FROM (
|
|||||||
CASE
|
CASE
|
||||||
WHEN SUM(CASE
|
WHEN SUM(CASE
|
||||||
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
|
ELSE 0
|
||||||
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
|
|
||||||
ELSE 1
|
|
||||||
END) > 0
|
END) > 0
|
||||||
THEN SUM(performance_score * CASE
|
THEN SUM(performance_score * CASE
|
||||||
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
|
ELSE 0
|
||||||
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
|
|
||||||
ELSE 1
|
|
||||||
END) / NULLIF(SUM(CASE
|
END) / NULLIF(SUM(CASE
|
||||||
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 THEN stock_qty
|
|
||||||
ELSE 1
|
|
||||||
END),0)
|
|
||||||
ELSE 0
|
ELSE 0
|
||||||
|
END),0)
|
||||||
|
ELSE COALESCE(AVG(performance_score),0)
|
||||||
END AS performance_score,
|
END AS performance_score,
|
||||||
MODE() WITHIN GROUP (ORDER BY performance_bucket) AS performance_bucket,
|
MODE() WITHIN GROUP (ORDER BY performance_bucket) AS performance_bucket,
|
||||||
COALESCE(MODE() WITHIN GROUP (ORDER BY NULLIF(recommendation,'')), '') AS recommendation,
|
COALESCE(MODE() WITHIN GROUP (ORDER BY NULLIF(recommendation,'')), '') AS recommendation,
|
||||||
@@ -6841,20 +6832,7 @@ func productPerformanceScoreWeight(row map[string]any, suffix string) float64 {
|
|||||||
if weight := floatFromMap(row, "sales_qty_"+suffix); weight > 0 {
|
if weight := floatFromMap(row, "sales_qty_"+suffix); weight > 0 {
|
||||||
return weight
|
return weight
|
||||||
}
|
}
|
||||||
if weight := floatFromMap(row, "sales_usd_"+suffix); weight > 0 {
|
return 0
|
||||||
return weight
|
|
||||||
}
|
|
||||||
stockQty := floatFromMap(row, "stock_qty")
|
|
||||||
if stockQty <= 0 {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
if cost := floatFromMap(row, "cost_price_usd_"+suffix); cost > 0 {
|
|
||||||
return stockQty * cost
|
|
||||||
}
|
|
||||||
if cost := floatFromMap(row, "cost_price_usd"); cost > 0 {
|
|
||||||
return stockQty * cost
|
|
||||||
}
|
|
||||||
return stockQty
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func productPerformanceCostWeight(row map[string]any) float64 {
|
func productPerformanceCostWeight(row map[string]any) float64 {
|
||||||
|
|||||||
@@ -4011,12 +4011,7 @@ function scoreSuffixForMetric (field) {
|
|||||||
function scoreWeight (row, suffix) {
|
function scoreWeight (row, suffix) {
|
||||||
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)
|
return 0
|
||||||
if (salesUsd > 0) return salesUsd
|
|
||||||
const stockQty = Number(row?.stock_qty || 0)
|
|
||||||
if (stockQty <= 0) return 1
|
|
||||||
const costPrice = Number(row?.[`cost_price_usd_${suffix}`] || row?.cost_price_usd || 0)
|
|
||||||
return costPrice > 0 ? stockQty * costPrice : stockQty
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function weightedAverageScore (sourceRows, valueField, suffix) {
|
function weightedAverageScore (sourceRows, valueField, suffix) {
|
||||||
@@ -4256,10 +4251,10 @@ function withProductMargins (row) {
|
|||||||
const out = {
|
const out = {
|
||||||
...next,
|
...next,
|
||||||
avg_price_usd_365d: Number(next?.sales_qty_365d || 0) > 0 ? Number(next?.sales_usd_365d || 0) / Number(next?.sales_qty_365d || 0) : 0,
|
avg_price_usd_365d: Number(next?.sales_qty_365d || 0) > 0 ? Number(next?.sales_usd_365d || 0) / Number(next?.sales_qty_365d || 0) : 0,
|
||||||
stock_turnover_90d: existingOrStockTurnover(next?.stock_turnover_90d, next?.sales_qty_90d, next?.avg_stock_90d || next?.stock_qty, 90),
|
stock_turnover_90d: groupedOrExistingStockTurnover(next, '90d', 90),
|
||||||
stock_turnover_180d: existingOrStockTurnover(next?.stock_turnover_180d, next?.sales_qty_180d, next?.avg_stock_180d || next?.stock_qty, 180),
|
stock_turnover_180d: groupedOrExistingStockTurnover(next, '180d', 180),
|
||||||
stock_turnover_365d: existingOrStockTurnover(next?.stock_turnover_365d, next?.sales_qty_365d, next?.avg_stock_365d || next?.stock_qty, 360),
|
stock_turnover_365d: groupedOrExistingStockTurnover(next, '365d', 360),
|
||||||
stock_turnover_total: existingOrStockTurnover(next?.stock_turnover_total, next?.sales_qty_total, next?.avg_stock_total || next?.stock_qty, productPerformancePeriodDays(next, 'total'))
|
stock_turnover_total: groupedOrExistingStockTurnover(next, 'total', productPerformancePeriodDays(next, 'total'))
|
||||||
}
|
}
|
||||||
for (const suffix of ['90d', '180d', '365d', 'total']) {
|
for (const suffix of ['90d', '180d', '365d', 'total']) {
|
||||||
applyPeriodProfitFields(out, suffix)
|
applyPeriodProfitFields(out, suffix)
|
||||||
@@ -4272,7 +4267,7 @@ function withGeneralMargins (row) {
|
|||||||
applyPeriodProfitFields(out, 'total')
|
applyPeriodProfitFields(out, 'total')
|
||||||
return {
|
return {
|
||||||
...out,
|
...out,
|
||||||
stock_turnover_total: existingOrStockTurnover(out?.stock_turnover_total, out?.sales_qty_total, out?.avg_stock_total || out?.stock_qty, productPerformancePeriodDays(out, 'total'))
|
stock_turnover_total: groupedOrExistingStockTurnover(out, 'total', productPerformancePeriodDays(out, 'total'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4348,6 +4343,15 @@ function existingOrStockTurnover (value, salesQty, stockQty, periodDays) {
|
|||||||
return value !== undefined && value !== null && Number.isFinite(current) ? current : stockTurnover(salesQty, stockQty, periodDays)
|
return value !== undefined && value !== null && Number.isFinite(current) ? current : stockTurnover(salesQty, stockQty, periodDays)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function groupedOrExistingStockTurnover (row, suffix, periodDays) {
|
||||||
|
const stockBase = Number(row?.[`avg_stock_${suffix}`] || row?.stock_qty || 0)
|
||||||
|
const salesQty = Number(row?.[`sales_qty_${suffix}`] || 0)
|
||||||
|
if (row?.__group) {
|
||||||
|
return stockTurnover(salesQty, stockBase, periodDays)
|
||||||
|
}
|
||||||
|
return existingOrStockTurnover(row?.[`stock_turnover_${suffix}`], salesQty, stockBase, periodDays)
|
||||||
|
}
|
||||||
|
|
||||||
function filterKey (tableKey, name) {
|
function filterKey (tableKey, name) {
|
||||||
return `${tableKey}:${name}`
|
return `${tableKey}:${name}`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user