Fix product performance grouped JSON build
This commit is contained in:
@@ -1670,6 +1670,7 @@ const productPerformanceExcelExportFilterFields = new Set([
|
||||
'color_yaka',
|
||||
'color_code',
|
||||
'yaka_kodu',
|
||||
'market_key',
|
||||
'performance_bucket'
|
||||
])
|
||||
const performanceTabs = [
|
||||
@@ -1815,16 +1816,16 @@ const columns = [
|
||||
{ name: 'stock_days_180d', label: '180G Stok Gün', field: row => formatNumber(row.stock_days_180d, 1), align: 'right', sortable: true },
|
||||
{ name: 'stock_days_365d', label: '360G Stok Gün', field: row => formatNumber(row.stock_days_365d, 1), align: 'right', sortable: true },
|
||||
{ name: 'stock_days_total', label: 'Genel Stok Gün', field: row => formatNumber(row.stock_days_total, 1), align: 'right', sortable: true },
|
||||
{ name: 'stock_turnover_90d', label: '90G Stok Devir', field: row => formatNumber(row.stock_turnover_90d, 2), align: 'right', sortable: true },
|
||||
{ name: 'stock_turnover_180d', label: '180G Stok Devir', field: row => formatNumber(row.stock_turnover_180d, 2), align: 'right', sortable: true },
|
||||
{ name: 'stock_turnover_365d', label: '360G Stok Devir', field: row => formatNumber(row.stock_turnover_365d, 2), align: 'right', sortable: true },
|
||||
{ name: 'stock_turnover_total', label: 'Genel Stok Devir', field: row => formatNumber(row.stock_turnover_total, 2), align: 'right', sortable: true },
|
||||
{ name: 'avg_price_usd_90d', label: 'Ort. USD', field: row => formatMoney(row.avg_price_usd_90d, 'USD'), align: 'right' },
|
||||
{ name: 'avg_price_usd_180d', label: '180G Ort. USD', field: row => formatMoney(row.avg_price_usd_180d, 'USD'), align: 'right' },
|
||||
{ name: 'avg_price_usd_365d', label: '360G Ort. USD', field: row => formatMoney(row.avg_price_usd_365d, 'USD'), align: 'right' },
|
||||
{ name: 'avg_price_usd_total', label: 'Genel Ort. USD', field: row => formatMoney(row.avg_price_usd_total, 'USD'), align: 'right' },
|
||||
{ name: 'base_price_usd', label: 'Ort. USD Taban Maliyeti', field: row => formatMoney(row.base_price_usd, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'cost_price_usd', label: 'Ort. USD Çıplak Maliyeti', field: row => formatMoney(row.cost_price_usd, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'stock_turnover_90d', label: '90G Satış/Stok', field: row => formatNumber(row.stock_turnover_90d, 2), align: 'right', sortable: true },
|
||||
{ name: 'stock_turnover_180d', label: '180G Satış/Stok', field: row => formatNumber(row.stock_turnover_180d, 2), align: 'right', sortable: true },
|
||||
{ name: 'stock_turnover_365d', label: '360G Satış/Stok', field: row => formatNumber(row.stock_turnover_365d, 2), align: 'right', sortable: true },
|
||||
{ name: 'stock_turnover_total', label: 'Genel Satış/Stok', field: row => formatNumber(row.stock_turnover_total, 2), align: 'right', sortable: true },
|
||||
{ name: 'avg_price_usd_90d', label: '90G Ciro/Adet USD', field: row => formatMoney(row.avg_price_usd_90d, 'USD'), align: 'right' },
|
||||
{ name: 'avg_price_usd_180d', label: '180G Ciro/Adet USD', field: row => formatMoney(row.avg_price_usd_180d, 'USD'), align: 'right' },
|
||||
{ name: 'avg_price_usd_365d', label: '360G Ciro/Adet USD', field: row => formatMoney(row.avg_price_usd_365d, 'USD'), align: 'right' },
|
||||
{ name: 'avg_price_usd_total', label: 'Genel Ciro/Adet USD', field: row => formatMoney(row.avg_price_usd_total, 'USD'), align: 'right' },
|
||||
{ name: 'base_price_usd', label: 'USD Taban Maliyeti', field: row => formatMoney(row.base_price_usd, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'cost_price_usd', label: 'USD Çıplak Maliyeti', field: row => formatMoney(row.cost_price_usd, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'unit_profit_base_90d', label: '90G P.Başı Taban K/Z', field: row => formatMoney(row.unit_profit_base_90d, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'unit_profit_cost_90d', label: '90G P.Başı Çıplak K/Z', field: row => formatMoney(row.unit_profit_cost_90d, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'unit_profit_base_180d', label: '180G P.Başı Taban K/Z', field: row => formatMoney(row.unit_profit_base_180d, 'USD'), align: 'right', sortable: true },
|
||||
@@ -1834,6 +1835,8 @@ const columns = [
|
||||
{ name: 'gross_profit_usd_90d', label: '90G Toplam K/Z', field: row => formatMoney(row.gross_profit_usd_90d, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'gross_profit_usd_180d', label: '180G Toplam K/Z', field: row => formatMoney(row.gross_profit_usd_180d, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'gross_profit_usd_total', label: 'Genel Toplam K/Z', field: row => formatMoney(row.gross_profit_usd_total, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'gross_profit_base_usd_total', label: 'Genel Taban K/Z', field: row => formatMoney(row.gross_profit_base_usd_total, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'gross_profit_cost_usd_total', label: 'Genel Çıplak K/Z', field: row => formatMoney(row.gross_profit_cost_usd_total, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'gross_margin_base_90d', label: '90G Taban Marj', field: row => formatPercent(row.gross_margin_base_90d), align: 'right', sortable: true },
|
||||
{ name: 'gross_margin_cost_90d', label: '90G Çıplak Marj', field: row => formatPercent(row.gross_margin_cost_90d), align: 'right', sortable: true },
|
||||
{ name: 'gross_margin_base_180d', label: '180G Taban Marj', field: row => formatPercent(row.gross_margin_base_180d), align: 'right', sortable: true },
|
||||
@@ -1865,7 +1868,23 @@ const periodOrder = {
|
||||
total: 4
|
||||
}
|
||||
|
||||
const hiddenTableColumns = new Set(['item_description', 'performance_score'])
|
||||
const hiddenTableColumns = new Set([
|
||||
'item_description',
|
||||
'performance_score',
|
||||
'gross_profit_usd_total',
|
||||
'invoice_count_90d',
|
||||
'invoice_count_180d',
|
||||
'invoice_count_365d',
|
||||
'invoice_count_total',
|
||||
'sales_index_90d',
|
||||
'sales_index_180d',
|
||||
'sales_index_365d',
|
||||
'sales_index_total',
|
||||
'stock_days_90d',
|
||||
'stock_days_180d',
|
||||
'stock_days_365d',
|
||||
'stock_days_total'
|
||||
])
|
||||
const dimensionColumnNames = [
|
||||
'product_code',
|
||||
'color_yaka',
|
||||
@@ -2022,16 +2041,18 @@ const generalColumns = [
|
||||
{ name: 'period_start', label: 'Başlangıç', field: 'period_start', align: 'left', sortable: true },
|
||||
{ name: 'period_end', label: 'Bitiş', field: 'period_end', align: 'left', sortable: true },
|
||||
{ name: 'stock_qty', label: 'Stok', field: row => formatNumber(row.stock_qty, 0), align: 'right', sortable: true },
|
||||
{ name: 'sales_qty_total', label: 'Toplam Satış', field: row => formatNumber(row.sales_qty_total, 0), align: 'right', sortable: true },
|
||||
{ name: 'sales_usd_total', label: 'Toplam USD', field: row => formatMoney(row.sales_usd_total, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'sales_qty_total', label: 'Toplam Adet', field: row => formatNumber(row.sales_qty_total, 0), align: 'right', sortable: true },
|
||||
{ name: 'sales_usd_total', label: 'Toplam Ciro USD', field: row => formatMoney(row.sales_usd_total, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'avg_daily_sales_total', label: 'Günlük Ort.', field: row => formatNumber(row.avg_daily_sales_total, 3), align: 'right', sortable: true },
|
||||
{ name: 'stock_days_total', label: 'Genel Stok Gün', field: row => formatNumber(row.stock_days_total, 1), align: 'right', sortable: true },
|
||||
{ name: 'avg_price_usd_total', label: 'Genel Ort. USD', field: row => formatMoney(row.avg_price_usd_total, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'avg_price_usd_total', label: 'Genel Ciro/Adet USD', field: row => formatMoney(row.avg_price_usd_total, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'base_price_usd', label: 'USD Taban Maliyeti', field: row => formatMoney(row.base_price_usd, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'cost_price_usd', label: 'USD Çıplak Maliyeti', field: row => formatMoney(row.cost_price_usd, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'unit_profit_base_total', label: 'P.Başı Taban K/Z', field: row => formatMoney(row.unit_profit_base_total, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'unit_profit_cost_total', label: 'P.Başı Çıplak K/Z', field: row => formatMoney(row.unit_profit_cost_total, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'gross_profit_usd_total', label: 'Toplam K/Z', field: row => formatMoney(row.gross_profit_usd_total, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'gross_profit_base_usd_total', label: 'Taban Toplam K/Z', field: row => formatMoney(row.gross_profit_base_usd_total, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'gross_profit_cost_usd_total', label: 'Çıplak Toplam K/Z', field: row => formatMoney(row.gross_profit_cost_usd_total, 'USD'), align: 'right', sortable: true },
|
||||
{ name: 'gross_margin_base_total', label: 'Genel Taban Marj', field: row => formatPercent(row.gross_margin_base_total), align: 'right', sortable: true },
|
||||
{ name: 'gross_margin_cost_total', label: 'Genel Çıplak Marj', field: row => formatPercent(row.gross_margin_cost_total), align: 'right', sortable: true },
|
||||
{ name: 'market_count_total', label: 'Toplam Piyasa', field: row => formatNumber(row.market_count_total, 0), align: 'right', sortable: true },
|
||||
@@ -2338,27 +2359,27 @@ const metricLabelOverrides = {
|
||||
sales_usd_180d: '180G Toplam Ciro USD',
|
||||
sales_usd_365d: '360G Toplam Ciro USD',
|
||||
sales_usd_total: 'Genel Toplam Ciro USD',
|
||||
avg_price_usd: 'Ağ. Ort. Fiyat USD',
|
||||
avg_price_usd_90d: '90G Ağ. Ort. Fiyat USD',
|
||||
avg_price_usd_180d: '180G Ağ. Ort. Fiyat USD',
|
||||
avg_price_usd_365d: '360G Ağ. Ort. Fiyat USD',
|
||||
avg_price_usd_total: 'Genel Ağ. Ort. Fiyat USD',
|
||||
base_price_usd: 'Ort. Taban Maliyet USD',
|
||||
cost_price_usd: 'Ort. Çıplak Maliyet USD',
|
||||
base_price_usd_90d: '90G Ort. Taban Maliyet USD',
|
||||
cost_price_usd_90d: '90G Ort. Çıplak Maliyet USD',
|
||||
base_price_usd_180d: '180G Ort. Taban Maliyet USD',
|
||||
cost_price_usd_180d: '180G Ort. Çıplak Maliyet USD',
|
||||
base_price_usd_365d: '360G Ort. Taban Maliyet USD',
|
||||
cost_price_usd_365d: '360G Ort. Çıplak Maliyet USD',
|
||||
base_price_usd_total: 'Genel Ort. Taban Maliyet USD',
|
||||
cost_price_usd_total: 'Genel Ort. Çıplak Maliyet USD',
|
||||
unit_profit_base_90d: '90G Ağ. Ort. Birim Taban K/Z USD',
|
||||
unit_profit_cost_90d: '90G Ağ. Ort. Birim Çıplak K/Z USD',
|
||||
unit_profit_base_180d: '180G Ağ. Ort. Birim Taban K/Z USD',
|
||||
unit_profit_cost_180d: '180G Ağ. Ort. Birim Çıplak K/Z USD',
|
||||
unit_profit_base_total: 'Genel Ağ. Ort. Birim Taban K/Z USD',
|
||||
unit_profit_cost_total: 'Genel Ağ. Ort. Birim Çıplak K/Z USD',
|
||||
avg_price_usd: 'Ciro/Adet USD',
|
||||
avg_price_usd_90d: '90G Ciro/Adet USD',
|
||||
avg_price_usd_180d: '180G Ciro/Adet USD',
|
||||
avg_price_usd_365d: '360G Ciro/Adet USD',
|
||||
avg_price_usd_total: 'Genel Ciro/Adet USD',
|
||||
base_price_usd: 'Taban Maliyet USD',
|
||||
cost_price_usd: 'Çıplak Maliyet USD',
|
||||
base_price_usd_90d: '90G Taban Maliyet USD',
|
||||
cost_price_usd_90d: '90G Çıplak Maliyet USD',
|
||||
base_price_usd_180d: '180G Taban Maliyet USD',
|
||||
cost_price_usd_180d: '180G Çıplak Maliyet USD',
|
||||
base_price_usd_365d: '360G Taban Maliyet USD',
|
||||
cost_price_usd_365d: '360G Çıplak Maliyet USD',
|
||||
base_price_usd_total: 'Genel Taban Maliyet USD',
|
||||
cost_price_usd_total: 'Genel Çıplak Maliyet USD',
|
||||
unit_profit_base_90d: '90G Birim Taban K/Z USD',
|
||||
unit_profit_cost_90d: '90G Birim Çıplak K/Z USD',
|
||||
unit_profit_base_180d: '180G Birim Taban K/Z USD',
|
||||
unit_profit_cost_180d: '180G Birim Çıplak K/Z USD',
|
||||
unit_profit_base_total: 'Genel Birim Taban K/Z USD',
|
||||
unit_profit_cost_total: 'Genel Birim Çıplak K/Z USD',
|
||||
gross_profit_usd_90d: '90G Toplam K/Z USD',
|
||||
gross_profit_usd_180d: '180G Toplam K/Z USD',
|
||||
gross_profit_usd_total: 'Genel Toplam K/Z USD',
|
||||
@@ -2370,33 +2391,37 @@ const metricLabelOverrides = {
|
||||
gross_profit_cost_usd_365d: '360G Çıplak Toplam K/Z USD',
|
||||
gross_profit_base_usd_total: 'Genel Taban Toplam K/Z USD',
|
||||
gross_profit_cost_usd_total: 'Genel Çıplak Toplam K/Z USD',
|
||||
gross_margin_base_90d: '90G Ağ. Ort. Taban Marj',
|
||||
gross_margin_cost_90d: '90G Ağ. Ort. Çıplak Marj',
|
||||
gross_margin_base_180d: '180G Ağ. Ort. Taban Marj',
|
||||
gross_margin_cost_180d: '180G Ağ. Ort. Çıplak Marj',
|
||||
gross_margin_base_365d: '360G Ağ. Ort. Taban Marj',
|
||||
gross_margin_cost_365d: '360G Ağ. Ort. Çıplak Marj',
|
||||
gross_margin_base_total: 'Genel Ağ. Ort. Taban Marj',
|
||||
gross_margin_cost_total: 'Genel Ağ. Ort. Çıplak Marj',
|
||||
performance_score: 'Ağ. Ort. Skor',
|
||||
performance_score_90d: '90G Ağ. Ort. Ürün Skor',
|
||||
performance_score_180d: '180G Ağ. Ort. Ürün Skor',
|
||||
performance_score_365d: '360G Ağ. Ort. Ürün Skor',
|
||||
performance_score_total: 'Genel Ağ. Ort. Ürün Skor',
|
||||
customer_score_90d: '90G Ağ. Ort. Müşteri Skor',
|
||||
customer_score_180d: '180G Ağ. Ort. Müşteri Skor',
|
||||
customer_score_365d: '360G Ağ. Ort. Müşteri Skor',
|
||||
customer_score_total: 'Genel Ağ. Ort. Müşteri Skor',
|
||||
gross_margin_base_90d: '90G Taban Marj',
|
||||
gross_margin_cost_90d: '90G Çıplak Marj',
|
||||
gross_margin_base_180d: '180G Taban Marj',
|
||||
gross_margin_cost_180d: '180G Çıplak Marj',
|
||||
gross_margin_base_365d: '360G Taban Marj',
|
||||
gross_margin_cost_365d: '360G Çıplak Marj',
|
||||
gross_margin_base_total: 'Genel Taban Marj',
|
||||
gross_margin_cost_total: 'Genel Çıplak Marj',
|
||||
performance_score: 'Skor',
|
||||
performance_score_90d: '90G Ürün Skor',
|
||||
performance_score_180d: '180G Ürün Skor',
|
||||
performance_score_365d: '360G Ürün Skor',
|
||||
performance_score_total: 'Genel Ürün Skor',
|
||||
customer_score_90d: '90G Müşteri Skor',
|
||||
customer_score_180d: '180G Müşteri Skor',
|
||||
customer_score_365d: '360G Müşteri Skor',
|
||||
customer_score_total: 'Genel Müşteri Skor',
|
||||
market_count_90d: '90G Tekil Piyasa',
|
||||
customer_count_90d: '90G Tekil Müşteri',
|
||||
market_count_total: 'Genel Tekil Piyasa',
|
||||
customer_count_total: 'Genel Tekil Müşteri',
|
||||
sales_index_90d: '90G Ağ. Ort. Endeks',
|
||||
sales_index_total: 'Genel Ağ. Ort. Endeks',
|
||||
stock_days_90d: '90G Ağ. Ort. Stok Gün',
|
||||
stock_days_180d: '180G Ağ. Ort. Stok Gün',
|
||||
stock_days_365d: '360G Ağ. Ort. Stok Gün',
|
||||
stock_days_total: 'Genel Ağ. Ort. Stok Gün',
|
||||
stock_turnover_90d: '90G Satış/Stok',
|
||||
stock_turnover_180d: '180G Satış/Stok',
|
||||
stock_turnover_365d: '360G Satış/Stok',
|
||||
stock_turnover_total: 'Genel Satış/Stok',
|
||||
sales_index_90d: '90G Endeks',
|
||||
sales_index_total: 'Genel Endeks',
|
||||
stock_days_90d: '90G Stok Gün',
|
||||
stock_days_180d: '180G Stok Gün',
|
||||
stock_days_365d: '360G Stok Gün',
|
||||
stock_days_total: 'Genel Stok Gün',
|
||||
avg_daily_sales_total: 'Genel Günlük Ort. Adet'
|
||||
}
|
||||
|
||||
@@ -3365,10 +3390,10 @@ function makeGroupRow (key, level, groupDef, value, groupRows) {
|
||||
gross_profit_usd_90d: sumRows(groupRows, 'gross_profit_usd_90d'),
|
||||
gross_profit_usd_180d: sumRows(groupRows, 'gross_profit_usd_180d'),
|
||||
gross_profit_usd_total: sumRows(groupRows, 'gross_profit_usd_total'),
|
||||
market_count_90d: distinctCount(groupRows, 'market_key'),
|
||||
customer_count_90d: sumRows(groupRows, 'customer_count_90d'),
|
||||
market_count_total: sumRows(groupRows, 'market_count_total'),
|
||||
customer_count_total: sumRows(groupRows, 'customer_count_total'),
|
||||
market_count_90d: distinctSpreadCount(groupRows, 'market_count_90d'),
|
||||
customer_count_90d: distinctSpreadCount(groupRows, 'customer_count_90d'),
|
||||
market_count_total: distinctSpreadCount(groupRows, 'market_count_total'),
|
||||
customer_count_total: distinctSpreadCount(groupRows, 'customer_count_total'),
|
||||
avg_price_usd_90d: weightedAverage(groupRows, 'sales_usd_90d', 'sales_qty_90d'),
|
||||
avg_price_usd_180d: weightedAverage(groupRows, 'sales_usd_180d', 'sales_qty_180d'),
|
||||
avg_price_usd_365d: weightedAverage(groupRows, 'sales_usd_365d', 'sales_qty_365d'),
|
||||
@@ -3425,6 +3450,10 @@ function aggregateGroupFields (sourceRows, groupField = '') {
|
||||
out[field] = weightedAverageProductCost(sourceRows, field)
|
||||
continue
|
||||
}
|
||||
if (isDistinctSpreadCountField(field)) {
|
||||
out[field] = distinctSpreadCount(sourceRows, field)
|
||||
continue
|
||||
}
|
||||
if (shouldSumField(field)) {
|
||||
out[field] = sumRows(sourceRows, field)
|
||||
} else if (shouldAverageField(field)) {
|
||||
@@ -3576,8 +3605,9 @@ function periodMetricSource (row, suffix) {
|
||||
}
|
||||
}
|
||||
|
||||
function productScore100 ({ suffix = '90d', salesUSD = 0, salesIndex = 0, margin = 0, stockTurnover = 0, marketCount = 0, customerCount = 0 } = {}) {
|
||||
const revenue = salesIndex > 0 ? ratioScore(salesIndex, 2) : ratioScore(salesUSD, productRevenueTarget(suffix))
|
||||
function productScore100 ({ suffix = '90d', salesUSD = 0, margin = 0, stockTurnover = 0, marketCount = 0, customerCount = 0 } = {}) {
|
||||
if (Number(salesUSD || 0) <= 0) return 1
|
||||
const revenue = ratioScore(salesUSD, productRevenueTarget(suffix))
|
||||
return clampScore(
|
||||
0.30 * marginScore(margin) +
|
||||
0.20 * ratioScore(stockTurnover, 1.5) +
|
||||
@@ -3588,6 +3618,7 @@ function productScore100 ({ suffix = '90d', salesUSD = 0, salesIndex = 0, margin
|
||||
}
|
||||
|
||||
function customerScore100 ({ suffix = '90d', salesUSD = 0, margin = 0, productGroupCount = 0, salesQty = 0 } = {}) {
|
||||
if (Number(salesUSD || 0) <= 0) return 1
|
||||
return clampScore(
|
||||
0.35 * ratioScore(salesUSD, customerRevenueTarget(suffix)) +
|
||||
0.30 * marginScore(margin) +
|
||||
@@ -3708,6 +3739,56 @@ function distinctCount (sourceRows, field) {
|
||||
return values.size
|
||||
}
|
||||
|
||||
function isDistinctSpreadCountField (field) {
|
||||
return /^market_count(_|$)/i.test(field) || /^customer_count(_|$)/i.test(field)
|
||||
}
|
||||
|
||||
function countPeriodSuffix (field) {
|
||||
if (field.includes('_180d')) return '180d'
|
||||
if (field.includes('_365d')) return '365d'
|
||||
if (field.includes('_total')) return 'total'
|
||||
return '90d'
|
||||
}
|
||||
|
||||
function salesUsdFieldForSuffix (suffix) {
|
||||
return `sales_usd_${suffix}`
|
||||
}
|
||||
|
||||
function distinctSpreadCount (sourceRows, field) {
|
||||
const suffix = countPeriodSuffix(field)
|
||||
return /^market_count/i.test(field)
|
||||
? distinctRevenueMarketCount(sourceRows, suffix, field)
|
||||
: distinctRevenueCustomerCount(sourceRows, suffix, field)
|
||||
}
|
||||
|
||||
function distinctRevenueMarketCount (sourceRows, suffix, fallbackField) {
|
||||
const salesField = salesUsdFieldForSuffix(suffix)
|
||||
const values = new Set()
|
||||
for (const row of sourceRows) {
|
||||
if (Number(row?.[salesField] || 0) <= 0) continue
|
||||
const value = displayMarketName(row?.market_key)
|
||||
if (value && value !== 'STOK' && value !== '-') values.add(value)
|
||||
}
|
||||
if (values.size > 0) return values.size
|
||||
return sourceRows.reduce((sum, row) => {
|
||||
return Number(row?.[salesField] || 0) > 0 ? sum + Number(row?.[fallbackField] || 0) : sum
|
||||
}, 0)
|
||||
}
|
||||
|
||||
function distinctRevenueCustomerCount (sourceRows, suffix, fallbackField) {
|
||||
const salesField = salesUsdFieldForSuffix(suffix)
|
||||
const values = new Set()
|
||||
for (const row of sourceRows) {
|
||||
if (Number(row?.[salesField] || 0) <= 0) continue
|
||||
const code = String(row?.customer_code || '').trim()
|
||||
if (code && code !== '-') values.add(code)
|
||||
}
|
||||
if (values.size > 0) return values.size
|
||||
return sourceRows.reduce((sum, row) => {
|
||||
return Number(row?.[salesField] || 0) > 0 ? sum + Number(row?.[fallbackField] || 0) : sum
|
||||
}, 0)
|
||||
}
|
||||
|
||||
function distinctSummary (sourceRows, field, fallbackField) {
|
||||
const values = new Set()
|
||||
for (const row of sourceRows) {
|
||||
|
||||
Reference in New Issue
Block a user