@@ -1784,7 +1784,7 @@ const detailSalesColumns = [
{ name : 'customer_name' , label : 'Müşteri' , field : 'customer_name' , align : 'left' , sortable : true } ,
{ name : 'sales_qty' , label : 'Adet' , field : row => formatNumber ( row . sales _qty , 2 ) , align : 'right' , sortable : true } ,
{ name : 'sales_usd' , label : 'USD' , field : row => formatMoney ( row . sales _usd , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'avg_price_usd' , label : 'Ort. USD' , field : row => formatMoney ( row . avg _price _usd , 'USD' ) , align : 'right' , sortable : true }
{ name : 'avg_price_usd' , label : 'Ort. Satış Fiyatı USD' , field : row => formatMoney ( row . avg _price _usd , 'USD' ) , align : 'right' , sortable : true }
]
const columns = [
@@ -1816,14 +1816,14 @@ 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 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 : 'stock_turnover_90d' , label : '90G Stok Devir Hı zı ' , field : row => formatNumber ( row . stock _turnover _90d , 2 ) , align : 'right' , sortable : true } ,
{ name : 'stock_turnover_180d' , label : '180G Stok Devir Hı zı ' , field : row => formatNumber ( row . stock _turnover _180d , 2 ) , align : 'right' , sortable : true } ,
{ name : 'stock_turnover_365d' , label : '360G Stok Devir Hı zı ' , field : row => formatNumber ( row . stock _turnover _365d , 2 ) , align : 'right' , sortable : true } ,
{ name : 'stock_turnover_total' , label : 'Genel Stok Devir Hı zı ' , field : row => formatNumber ( row . stock _turnover _total , 2 ) , align : 'right' , sortable : true } ,
{ name : 'avg_price_usd_90d' , label : '90G Ort. Satış Fiyatı USD' , field : row => formatMoney ( row . avg _price _usd _90d , 'USD' ) , align : 'right' } ,
{ name : 'avg_price_usd_180d' , label : '180G Ort. Satış Fiyatı USD' , field : row => formatMoney ( row . avg _price _usd _180d , 'USD' ) , align : 'right' } ,
{ name : 'avg_price_usd_365d' , label : '360G Ort. Satış Fiyatı USD' , field : row => formatMoney ( row . avg _price _usd _365d , 'USD' ) , align : 'right' } ,
{ name : 'avg_price_usd_total' , label : 'Genel Ort. Satış Fiyatı 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 } ,
@@ -2045,7 +2045,7 @@ const generalColumns = [
{ 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 Ciro/Adet USD' , field : row => formatMoney ( row . avg _price _usd _total , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'avg_price_usd_total' , label : 'Genel Ort. Satış Fiyatı 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 } ,
@@ -2108,7 +2108,7 @@ const orderGroupColumns = [
{ name : 'product_count' , label : 'Ürün' , field : row => formatNumber ( row . product _count , 0 ) , align : 'right' , sortable : true } ,
{ name : 'order_qty' , label : 'Açık Sipariş' , field : row => formatNumber ( row . order _qty , 0 ) , align : 'right' , sortable : true } ,
{ name : 'order_usd' , label : 'Sipariş USD' , field : row => formatMoney ( row . order _usd , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'avg_order_price_usd' , label : 'Ort. USD' , field : row => formatMoney ( row . avg _order _price _usd , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'avg_order_price_usd' , label : 'Ort. Sipariş Fiyatı USD' , field : row => formatMoney ( row . avg _order _price _usd , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'base_cost_usd' , label : 'Taban Maliyet USD' , field : row => formatMoney ( row . base _cost _usd , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'cost_amount_usd' , label : 'Çıplak Maliyet USD' , field : row => formatMoney ( row . cost _amount _usd , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'expected_profit_base_usd' , label : 'Brüt K/Z' , field : row => formatMoney ( row . expected _profit _base _usd , 'USD' ) , align : 'right' , sortable : true } ,
@@ -2142,7 +2142,7 @@ const orderProductCustomerColumns = [
{ name : 'yaka_kodu' , label : 'Yaka' , field : 'yaka_kodu' , align : 'left' , sortable : true } ,
{ name : 'order_qty' , label : 'Açık Sipariş' , field : row => formatNumber ( row . order _qty , 0 ) , align : 'right' , sortable : true } ,
{ name : 'order_usd' , label : 'Sipariş USD' , field : row => formatMoney ( row . order _usd , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'avg_order_price_usd' , label : 'Ort. USD' , field : row => formatMoney ( row . avg _order _price _usd , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'avg_order_price_usd' , label : 'Ort. Sipariş Fiyatı USD' , field : row => formatMoney ( row . avg _order _price _usd , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'stock_qty' , label : 'Stok' , field : row => formatNumber ( row . stock _qty , 0 ) , align : 'right' , sortable : true } ,
{ name : 'net_stock_after_order' , label : 'Stok - Sipariş' , field : 'net_stock_after_order' , align : 'right' , sortable : true } ,
{ name : 'base_price_usd' , label : 'Taban USD' , field : row => formatMoney ( row . base _price _usd , 'USD' ) , align : 'right' , sortable : true } ,
@@ -2176,7 +2176,7 @@ const orderMarketDetailColumns = [
{ name : 'due_date' , label : 'Termin' , field : 'due_date' , align : 'left' , sortable : true } ,
{ name : 'order_qty' , label : 'Adet' , field : row => formatNumber ( row . order _qty , 0 ) , align : 'right' , sortable : true } ,
{ name : 'order_usd' , label : 'USD' , field : row => formatMoney ( row . order _usd , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'avg_order_price_usd' , label : 'Ort. USD' , field : row => formatMoney ( row . avg _order _price _usd , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'avg_order_price_usd' , label : 'Ort. Sipariş Fiyatı USD' , field : row => formatMoney ( row . avg _order _price _usd , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'stock_qty' , label : 'Stok' , field : row => formatNumber ( row . stock _qty , 0 ) , align : 'right' , sortable : true } ,
{ name : 'net_stock_after_order' , label : 'Stok - Sipariş' , field : 'net_stock_after_order' , align : 'right' , sortable : true } ,
{ name : 'expected_profit_base_usd' , label : 'Brüt K/Z' , field : row => formatMoney ( row . expected _profit _base _usd , 'USD' ) , align : 'right' , sortable : true } ,
@@ -2205,7 +2205,7 @@ const idleColumns = [
{ name : 'idle_cost_usd' , label : 'Stok Maliyeti USD' , field : 'idle_cost_usd' , align : 'right' , sortable : true } ,
{ name : 'sales_qty_90d' , label : '90G Satış' , field : row => formatNumber ( row . sales _qty _90d , 0 ) , align : 'right' , sortable : true } ,
{ name : 'stock_days_90d' , label : 'Stok Gün' , field : row => formatNumber ( row . stock _days _90d , 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_90d' , label : '90G Stok Devir Hı zı ' , field : row => formatNumber ( row . stock _turnover _90d , 2 ) , align : 'right' , sortable : true } ,
{ name : 'performance_bucket' , label : 'Durum' , field : 'performance_bucket' , align : 'left' } ,
{ name : 'recommendation' , label : 'Öneri' , field : 'recommendation' , align : 'left' }
]
@@ -2236,7 +2236,7 @@ const countryColumns = [
{ name : 'product_count' , label : 'Ürün' , field : row => formatNumber ( row . product _count , 0 ) , align : 'right' , sortable : true } ,
{ name : 'sales_qty_90d' , label : '90G Adet' , field : row => formatNumber ( row . sales _qty _90d , 0 ) , align : 'right' , sortable : true } ,
{ name : 'sales_usd_90d' , label : '90G USD' , field : row => formatMoney ( row . sales _usd _90d , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'avg_price_usd_90d' , label : 'Ort. USD' , field : row => formatMoney ( row . avg _price _usd _90d , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'avg_price_usd_90d' , label : 'Ort. Satış Fiyatı USD' , field : row => formatMoney ( row . avg _price _usd _90d , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'customer_count_90d' , label : 'Müşteri' , field : row => formatNumber ( row . customer _count _90d , 0 ) , align : 'right' , sortable : true } ,
{ name : 'invoice_count_90d' , label : 'Fatura' , field : row => formatNumber ( row . invoice _count _90d , 0 ) , align : 'right' , sortable : true } ,
{ name : 'sales_qty_365d' , label : '360G Adet' , field : row => formatNumber ( row . sales _qty _365d , 0 ) , align : 'right' , sortable : true } ,
@@ -2252,7 +2252,7 @@ const customerColumns = [
{ name : 'product_count' , label : 'Ürün' , field : row => formatNumber ( row . product _count , 0 ) , align : 'right' , sortable : true } ,
{ name : 'sales_qty_90d' , label : '90G Adet' , field : row => formatNumber ( row . sales _qty _90d , 0 ) , align : 'right' , sortable : true } ,
{ name : 'sales_usd_90d' , label : '90G USD' , field : 'sales_usd_90d' , align : 'right' , sortable : true } ,
{ name : 'avg_price_usd_90d' , label : 'Ort. USD' , field : 'avg_price_usd_90d' , align : 'right' , sortable : true } ,
{ name : 'avg_price_usd_90d' , label : 'Ort. Satış Fiyatı USD' , field : 'avg_price_usd_90d' , align : 'right' , sortable : true } ,
{ name : 'customer_score_90d' , label : '90G Müşteri Skor' , field : row => formatNumber ( row . customer _score _90d , 2 ) , align : 'right' , sortable : true } ,
{ name : 'base_price_usd_90d' , label : '90G Taban' , field : row => formatMoney ( row . base _price _usd _90d , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'cost_price_usd_90d' , label : '90G Çıplak' , field : row => formatMoney ( row . cost _price _usd _90d , 'USD' ) , align : 'right' , sortable : true } ,
@@ -2287,14 +2287,14 @@ const salesBreakdownColumns = [
{ name : 'invoice_count_90d' , label : '90G Fatura' , field : row => formatNumber ( row . invoice _count _90d , 0 ) , align : 'right' , sortable : true } ,
{ name : 'sales_qty_90d' , label : '90G Adet' , field : row => formatNumber ( row . sales _qty _90d , 0 ) , align : 'right' , sortable : true } ,
{ name : 'sales_usd_90d' , label : '90G USD' , field : 'sales_usd_90d' , align : 'right' , sortable : true } ,
{ name : 'avg_price_usd_90d' , label : 'Ort. USD' , field : 'avg_price_usd_90d' , 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 : 'avg_price_usd_90d' , label : '90G Ort. Satış Fiyatı USD' , field : 'avg_price_usd_90d' , align : 'right' , sortable : true } ,
{ name : 'stock_turnover_90d' , label : '90G Stok Devir Hı zı ' , field : row => formatNumber ( row . stock _turnover _90d , 2 ) , align : 'right' , sortable : true } ,
{ name : 'customer_count_180d' , label : '180G Müşteri' , field : row => formatNumber ( row . customer _count _180d , 0 ) , align : 'right' , sortable : true } ,
{ name : 'invoice_count_180d' , label : '180G Fatura' , field : row => formatNumber ( row . invoice _count _180d , 0 ) , align : 'right' , sortable : true } ,
{ name : 'sales_qty_180d' , label : '180G Adet' , field : row => formatNumber ( row . sales _qty _180d , 0 ) , align : 'right' , sortable : true } ,
{ name : 'sales_usd_180d' , label : '180G USD' , field : row => formatMoney ( row . sales _usd _180d , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'avg_price_usd_180d' , label : '180G Ort. USD' , field : row => formatMoney ( row . avg _price _usd _180d , 'USD' ) , 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 : 'avg_price_usd_180d' , label : '180G Ort. Satış Fiyatı USD' , field : row => formatMoney ( row . avg _price _usd _180d , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'stock_turnover_180d' , label : '180G Stok Devir Hı zı ' , field : row => formatNumber ( row . stock _turnover _180d , 2 ) , align : 'right' , sortable : true } ,
{ name : 'base_price_usd_180d' , label : '180G Taban' , field : row => formatMoney ( row . base _price _usd _180d , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'cost_price_usd_180d' , label : '180G Çıplak' , field : row => formatMoney ( row . cost _price _usd _180d , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'gross_profit_base_usd_180d' , label : '180G Taban K/Z' , field : row => formatMoney ( row . gross _profit _base _usd _180d , 'USD' ) , align : 'right' , sortable : true } ,
@@ -2304,8 +2304,8 @@ const salesBreakdownColumns = [
{ name : 'customer_score_180d' , label : '180G Müşteri Skor' , field : row => formatNumber ( row . customer _score _180d , 2 ) , align : 'right' , sortable : true } ,
{ name : 'sales_qty_365d' , label : '360G Adet' , field : row => formatNumber ( row . sales _qty _365d , 0 ) , align : 'right' , sortable : true } ,
{ name : 'sales_usd_365d' , label : '360G USD' , field : row => formatMoney ( row . sales _usd _365d , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'avg_price_usd_365d' , label : '360G Ort. USD' , field : row => formatMoney ( row . avg _price _usd _365d , 'USD' ) , 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 : 'avg_price_usd_365d' , label : '360G Ort. Satış Fiyatı USD' , field : row => formatMoney ( row . avg _price _usd _365d , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'stock_turnover_365d' , label : '360G Stok Devir Hı zı ' , field : row => formatNumber ( row . stock _turnover _365d , 2 ) , align : 'right' , sortable : true } ,
{ name : 'base_price_usd_365d' , label : '360G Taban' , field : row => formatMoney ( row . base _price _usd _365d , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'cost_price_usd_365d' , label : '360G Çıplak' , field : row => formatMoney ( row . cost _price _usd _365d , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'gross_profit_base_usd_365d' , label : '360G Taban K/Z' , field : row => formatMoney ( row . gross _profit _base _usd _365d , 'USD' ) , align : 'right' , sortable : true } ,
@@ -2317,8 +2317,8 @@ const salesBreakdownColumns = [
{ name : 'invoice_count_total' , label : 'Genel Fatura' , field : row => formatNumber ( row . invoice _count _total , 0 ) , align : 'right' , sortable : true } ,
{ name : 'sales_qty_total' , label : 'Genel Adet' , field : row => formatNumber ( row . sales _qty _total , 0 ) , align : 'right' , sortable : true } ,
{ name : 'sales_usd_total' , label : 'Genel USD' , field : row => formatMoney ( row . sales _usd _total , 'USD' ) , 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 : 'stock_turnover_total' , label : 'Genel Stok Devir' , field : row => formatNumber ( row . stock _turnover _total , 2 ) , align : 'right' , sortable : true } ,
{ name : 'avg_price_usd_total' , label : 'Genel Ort. Satış Fiyatı USD' , field : row => formatMoney ( row . avg _price _usd _total , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'stock_turnover_total' , label : 'Genel Stok Devir Hı zı ' , field : row => formatNumber ( row . stock _turnover _total , 2 ) , align : 'right' , sortable : true } ,
{ name : 'base_price_usd_total' , label : 'Genel Taban' , field : row => formatMoney ( row . base _price _usd _total , 'USD' ) , align : 'right' , sortable : true } ,
{ name : 'cost_price_usd_total' , label : 'Genel Çıplak' , field : row => formatMoney ( row . cost _price _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 } ,
@@ -2359,11 +2359,11 @@ 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 : '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' ,
avg _price _usd : 'Ort. Satış Fiyatı USD' ,
avg _price _usd _90d : '90G Ort. Satış Fiyatı USD' ,
avg _price _usd _180d : '180G Ort. Satış Fiyatı USD' ,
avg _price _usd _365d : '360G Ort. Satış Fiyatı USD' ,
avg _price _usd _total : 'Genel Ort. Satış Fiyatı USD' ,
base _price _usd : 'Taban Maliyet USD' ,
cost _price _usd : 'Çıplak Maliyet USD' ,
base _price _usd _90d : '90G Taban Maliyet USD' ,
@@ -2412,10 +2412,10 @@ const metricLabelOverrides = {
customer _count _90d : '90G Tekil Müşteri' ,
market _count _total : 'Genel Tekil Piyasa' ,
customer _count _total : 'Genel Tekil Müşteri' ,
stock _turnover _90d : '90G Satış/Stok ' ,
stock _turnover _180d : '180G Satış/Stok ' ,
stock _turnover _365d : '360G Satış/Stok ' ,
stock _turnover _total : 'Genel Satış/Stok ' ,
stock _turnover _90d : '90G Stok Devir Hı zı ' ,
stock _turnover _180d : '180G Stok Devir Hı zı ' ,
stock _turnover _365d : '360G Stok Devir Hı zı ' ,
stock _turnover _total : 'Genel Stok Devir Hı zı ' ,
sales _index _90d : '90G Endeks' ,
sales _index _total : 'Genel Endeks' ,
stock _days _90d : '90G Stok Gün' ,
@@ -2645,7 +2645,7 @@ function performanceCardsForRow (row) {
{ key : 'sales180' , label : '180G Satış' , value : formatNumber ( source . sales _qty _180d , 0 ) } ,
{ key : 'markets' , label : '90G Piyasa' , value : formatNumber ( source . market _count _90d , 0 ) } ,
{ key : 'customers' , label : '90G Müşteri' , value : formatNumber ( source . customer _count _90d , 0 ) } ,
{ key : 'avg' , label : 'Ort. USD S atı ş ' , value : formatMoney ( source . avg _price _usd _90d , 'USD' ) } ,
{ key : 'avg' , label : 'Ort. Satış Fiy atı ' , value : formatMoney ( source . avg _price _usd _90d , 'USD' ) } ,
{ key : 'base' , label : 'Taban Maliyet' , value : formatMoney ( source . base _price _usd , 'USD' ) } ,
{ key : 'cost' , label : 'Çıplak Maliyet' , value : formatMoney ( source . cost _price _usd , 'USD' ) } ,
{ key : 'profitBase' , label : 'P.Başı Taban K/Z' , value : formatMoney ( source . unit _profit _base _90d , 'USD' ) } ,
@@ -3470,7 +3470,7 @@ function shouldSumField (field) {
}
function shouldAverageField ( field ) {
return /^(avg_|unit_|base_price|cost_price|gross_margin|expected_margin|sales_index|performance_score|stock_days|stock_turnover)/i . test ( field ) ||
return /^(avg_|unit_|base_price|cost_price|gross_margin|expected_margin|sales_index|performance_score|customer_score| stock_days|stock_turnover)/i . test ( field ) ||
/(_price_usd|_margin|_index|_days)$/i . test ( field )
}
@@ -3484,21 +3484,35 @@ function weightFieldForMetric (field) {
}
function applyDerivedGroupMetrics ( out , sourceRows , groupField = '' ) {
Object . assign ( out , normalizeProductCostFields ( out ) )
for ( const suffix of [ '90d' , '180d' , '365d' , 'total' ] ) {
const sales = Number ( out [ ` sales_usd_ ${ suffix } ` ] || 0 )
const qty = Number ( out [ ` sales_qty_ ${ suffix } ` ] || 0 )
const stockQty = Number ( out . stock _qty || 0 )
const avgStock = Number ( out [ ` avg_stock_ ${ suffix } ` ] || 0 )
const turnoverBase = avgStock > 0 ? avgStock : stockQty
out [ ` stock_turnover_ ${ suffix } ` ] = turnoverBase > 0 ? qty / turnoverBase : 0
if ( qty > 0 ) out [ ` avg_price_usd_ ${ suffix } ` ] = sales / qty
if ( sales > 0 ) {
if ( out [ ` gross_profit_base_usd_ ${ suffix } ` ] != = undefined ) {
out [ ` gross_margin_base_ ${ suffix } ` ] = Number ( out [ ` gross_profit_base_usd_ ${ suffix } ` ] || 0 ) / sales
}
if ( out [ ` gross_profit_cost_usd_ ${ suffix } ` ] !== undefined ) {
out [ ` gross_margin_cost_ ${ suffix } ` ] = Number ( out [ ` gross_profit_cost_usd_ ${ suffix } ` ] || 0 ) / sales
}
if ( out [ ` gross_profit_usd_ ${ suffix } ` ] != = undefined ) {
out [ ` gross_margin_ ${ suffix } ` ] = Number ( out [ ` gross_profit_usd_ ${ suffix } ` ] || 0 ) / sales
}
const { costPrice , basePrice } = periodCostPair ( out , suffix )
out [ ` base_price_usd_ ${ suffix } ` ] = basePrice
out [ ` cost_price_usd_ ${ suffix } ` ] = costPrice
if ( qty > 0 ) {
const avgPrice = sales / qty
out [ ` unit_profit_base_ ${ suffix } ` ] = avgPrice - basePrice
out [ ` unit_profit_cost_ ${ suffix } ` ] = avgPrice - costPrice
out [ ` gross_profit_base_usd_ ${ suffix } ` ] = sales - qty * basePrice
out [ ` gross_profit_cost_usd_ ${ suffix } ` ] = sales - qty * costPrice
out [ ` gross_profit_usd_ ${ suffix } ` ] = out [ ` gross_profit_cost_usd_ ${ suffix } ` ]
} else {
out [ ` unit_profit_base_ ${ suffix } ` ] = 0
out [ ` unit_profit_cost_ ${ suffix } ` ] = 0
out [ ` gross_profit_base_usd_ ${ suffix } ` ] = 0
out [ ` gross_profit_cost_usd_ ${ suffix } ` ] = 0
out [ ` gross_profit_usd_ ${ suffix } ` ] = 0
}
out [ ` gross_margin_base_ ${ suffix } ` ] = sales > 0 ? Number ( out [ ` gross_profit_base_usd_ ${ suffix } ` ] || 0 ) / sales : 0
out [ ` gross_margin_cost_ ${ suffix } ` ] = sales > 0 ? Number ( out [ ` gross_profit_cost_usd_ ${ suffix } ` ] || 0 ) / sales : 0
out [ ` gross_margin_ ${ suffix } ` ] = sales > 0 ? Number ( out [ ` gross_profit_usd_ ${ suffix } ` ] || 0 ) / sales : 0
}
const orderUsd = Number ( out . order _usd || 0 )
@@ -3524,7 +3538,11 @@ function applyDerivedGroupMetrics (out, sourceRows, groupField = '') {
if ( ! Object . prototype . hasOwnProperty . call ( out , 'performance_score_180d' ) ) out . performance _score _180d = productSalesPeriodScore ( productPeriodMetricSource ( out , '180d' ) )
if ( ! Object . prototype . hasOwnProperty . call ( out , 'performance_score_365d' ) ) out . performance _score _365d = productSalesPeriodScore ( productPeriodMetricSource ( out , '365d' ) )
if ( ! Object . prototype . hasOwnProperty . call ( out , 'performance_score_total' ) ) out . performance _score _total = productSalesPeriodScore ( productPeriodMetricSource ( out , 'total' ) )
if ( ! Object . prototype . hasOwnProperty . call ( out , 'performance_score' ) ) out . performance _score = groupPerformanceScore ( out , groupField )
if ( ! Object . prototype . hasOwnProperty . call ( out , 'performance_score' ) ) {
out . performance _score = Object . prototype . hasOwnProperty . call ( out , 'performance_score_90d' )
? Number ( out . performance _score _90d || 0 )
: groupPerformanceScore ( out , groupField )
}
}
function groupPerformanceScore ( row , groupField = '' ) {
@@ -3837,6 +3855,9 @@ function weightedAverage (sourceRows, amountField, qtyField) {
}
function weightedAverageOrAverage ( sourceRows , valueField , qtyField ) {
if ( /^(performance_score|customer_score)/i . test ( valueField ) ) {
return weightedAverageScore ( sourceRows , valueField , scoreSuffixForMetric ( valueField ) )
}
const weightedRows = sourceRows
. map ( row => ( {
value : Number ( row [ valueField ] || 0 ) ,
@@ -3850,6 +3871,39 @@ function weightedAverageOrAverage (sourceRows, valueField, qtyField) {
return 0
}
function scoreSuffixForMetric ( field ) {
if ( field . includes ( '_180d' ) ) return '180d'
if ( field . includes ( '_365d' ) ) return '365d'
if ( field . includes ( '_total' ) ) return 'total'
return '90d'
}
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 )
if ( salesQty > 0 ) return salesQty
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 ) {
const rows = sourceRows
. filter ( row => Object . prototype . hasOwnProperty . call ( row || { } , valueField ) )
. map ( row => ( {
value : Number ( row [ valueField ] || 0 ) ,
weight : scoreWeight ( row , suffix )
} ) )
. filter ( row => Number . isFinite ( row . value ) && Number . isFinite ( row . weight ) )
const weight = rows . reduce ( ( sum , row ) => sum + Math . max ( 0 , row . weight ) , 0 )
if ( weight > 0 ) {
return rows . reduce ( ( sum , row ) => sum + row . value * Math . max ( 0 , row . weight ) , 0 ) / weight
}
return rows . length ? rows . reduce ( ( sum , row ) => sum + row . value , 0 ) / rows . length : 0
}
function weightedAverageProductCost ( sourceRows , valueField ) {
const salesRows = sourceRows
. map ( row => ( {
@@ -4068,53 +4122,93 @@ function formatGroupCell (row, colOrName) {
}
function withProductMargins ( row ) {
const salesQtyTotal = Number ( row ? . sales _qty _total || 0 )
const salesUSDTotal = Number ( row ? . sales _usd _total || 0 )
const basePrice = Number ( row ? . base _price _usd || 0 )
const costPrice = Number ( row ? . cost _price _usd || 0 )
const grossProfitBaseTotal = salesQtyTotal > 0 ? salesUSDTotal - ( salesQtyTotal * basePrice ) : 0
const grossProfitCostTotal = salesQtyTotal > 0 ? salesUSDTotal - ( salesQtyTotal * costPrice ) : 0
return {
... row ,
avg _price _usd _365d : Number ( row ? . sales _qty _365d || 0 ) > 0 ? Number ( row ? . sales _usd _365d || 0 ) / Number ( row ? . sales _qty _365d || 0 ) : 0 ,
avg _price _usd _total : salesQtyTotal > 0 ? salesUSDTotal / salesQtyTotal : Number ( row ? . avg _price _usd _total || 0 ) ,
stock _turnover _90d : existingOrStockTurnover ( row ? . stock _turnover _90d , row ? . sales _qty _90d , row ? . stock _qty ) ,
stock _turnover _180d : existingOrStockTurnover ( row ? . stock _turnover _180d , row ? . sales _qty _180d , row ? . stock _qty ) ,
stock _turnover _365d : existingOrStockTurnover ( row ? . stock _turnover _365d , row ? . sales _qty _365d , row ? . stock _qty ) ,
stock _turnover _total : existingOrStockTurnover ( row ? . stock _turnover _total , row ? . sales _qty _total , row ? . stock _qty ) ,
gross _profit _base _usd _total : grossProfitBaseTotal ,
gross _profit _cost _usd _total : grossProfitCostTotal ,
gross _profit _usd _total : Number ( row ? . gross _profit _usd _total ? ? grossProfitCostTotal ) ,
gross _margin _base _90d : marginFromSalesCost ( row ? . sales _usd _90d , row ? . sales _qty _90d , row ? . base _price _usd ) ,
gross _margin _cost _90d : marginFromSalesCost ( row ? . sales _usd _90d , row ? . sales _qty _90d , row ? . cost _price _usd ) ,
gross _margin _base _180d : marginFromSalesCost ( row ? . sales _usd _180d , row ? . sales _qty _180d , row ? . base _price _usd ) ,
gross _margin _cost _180d : marginFromSalesCost ( row ? . sales _usd _180d , row ? . sales _qty _180d , row ? . cost _price _usd ) ,
gross _margin _base _365d : marginFromSalesCost ( row ? . sales _usd _365d , row ? . sales _qty _365d , row ? . base _price _usd ) ,
gross _margin _cost _365d : marginFromSalesCost ( row ? . sales _usd _365d , row ? . sales _qty _365d , row ? . cost _price _usd ) ,
gross _margin _base _total : marginFromSalesCost ( salesUSDTotal , salesQtyTotal , basePrice ) ,
gross _margin _cost _total : marginFromSalesCost ( salesUSDTotal , salesQtyTotal , costPrice )
const next = normalizeProductCostFields ( row )
const out = {
... 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 ,
stock _turnover _90d : existingOrStockTurnover ( next ? . stock _turnover _90d , next ? . sales _qty _90d , next ? . stock _qty ) ,
stock _turnover _180d : existingOrStockTurnover ( next ? . stock _turnover _180d , next ? . sales _qty _180d , next ? . stock _qty ) ,
stock _turnover _365d : existingOrStockTurnover ( next ? . stock _turnover _365d , next ? . sales _qty _365d , next ? . stock _qty ) ,
stock _turnover _total : existingOrStockTurnover ( next ? . stock _turnover _total , next ? . sales _qty _total , next ? . stock _qty )
}
for ( const suffix of [ '90d' , '180d' , '365d' , 'total' ] ) {
applyPeriodProfitFields ( out , suffix )
}
return out
}
function withGeneralMargins ( row ) {
const salesQtyTotal = Number ( row ? . sales _qty _total || 0 )
const salesUSDTotal = Number ( row ? . sales _usd _total || 0 )
const basePrice = Number ( row ? . base _price _usd || 0 )
const costPrice = Number ( row ? . cost _price _usd || 0 )
const grossProfitBaseTotal = salesQtyTotal > 0 ? salesUSDTotal - ( salesQtyTotal * basePrice ) : 0
const grossProfitCostTotal = salesQtyTotal > 0 ? salesUSDTotal - ( salesQtyTotal * costPrice ) : 0
const out = normalizeProductCostFields ( row )
applyPeriodProfitFields ( out , 'total' )
return {
... row ,
avg _price _usd _total : salesQtyTotal > 0 ? salesUSDTotal / salesQtyTotal : Number ( row ? . avg _price _usd _total || 0 ) ,
stock _turnover _total : existingOrStockTurnover ( row ? . stock _turnover _total , row ? . sales _qty _total , row ? . stock _qty ) ,
gross _profit _base _usd _total : grossProfitBaseTotal ,
gross _profit _cost _usd _total : grossProfitCostTotal ,
gross _profit _usd _total : Number ( row ? . gross _profit _usd _total ? ? grossProfitCostTotal ) ,
gross _margin _base _total : marginFromSalesCost ( salesUSDTotal , salesQtyTotal , basePrice ) ,
gross _margin _cost _total : marginFromSalesCost ( salesUSDTotal , salesQtyTotal , costPrice )
... out ,
stock _turnover _total : existingOrStockTurnover ( out ? . stock _turnover _total , out ? . sales _qty _total , out ? . stock _qty )
}
}
function normalizeProductCostFields ( row ) {
const next = { ... row }
normalizeProductCostPairFields ( next , 'cost_price_usd' , 'base_price_usd' )
for ( const suffix of [ '90d' , '180d' , '365d' , 'total' ] ) {
normalizeProductCostPairFields ( next , ` cost_price_usd_ ${ suffix } ` , ` base_price_usd_ ${ suffix } ` )
}
return next
}
function normalizeProductCostPairFields ( row , costField , baseField ) {
const hasCost = Object . prototype . hasOwnProperty . call ( row || { } , costField )
const hasBase = Object . prototype . hasOwnProperty . call ( row || { } , baseField )
if ( ! hasCost && ! hasBase ) return
let costPrice = Number ( row ? . [ costField ] || 0 )
let basePrice = Number ( row ? . [ baseField ] || 0 )
if ( costPrice > 0 && basePrice > 0 && costPrice > basePrice ) {
const tmp = costPrice
costPrice = basePrice
basePrice = tmp
}
if ( hasCost || costPrice > 0 ) row [ costField ] = costPrice
if ( hasBase || basePrice > 0 ) row [ baseField ] = basePrice
}
function periodCostPair ( row , suffix ) {
const costField = ` cost_price_usd_ ${ suffix } `
const baseField = ` base_price_usd_ ${ suffix } `
let costPrice = Number ( row ? . [ costField ] || 0 )
let basePrice = Number ( row ? . [ baseField ] || 0 )
if ( costPrice <= 0 ) costPrice = Number ( row ? . cost _price _usd || 0 )
if ( basePrice <= 0 ) basePrice = Number ( row ? . base _price _usd || 0 )
if ( costPrice > 0 && basePrice > 0 && costPrice > basePrice ) {
const tmp = costPrice
costPrice = basePrice
basePrice = tmp
}
return { costPrice , basePrice }
}
function applyPeriodProfitFields ( row , suffix ) {
const qty = Number ( row ? . [ ` sales_qty_ ${ suffix } ` ] || 0 )
const salesUSD = Number ( row ? . [ ` sales_usd_ ${ suffix } ` ] || 0 )
const { costPrice , basePrice } = periodCostPair ( row , suffix )
row [ ` base_price_usd_ ${ suffix } ` ] = basePrice
row [ ` cost_price_usd_ ${ suffix } ` ] = costPrice
if ( qty > 0 ) {
row [ ` avg_price_usd_ ${ suffix } ` ] = salesUSD / qty
row [ ` unit_profit_base_ ${ suffix } ` ] = salesUSD / qty - basePrice
row [ ` unit_profit_cost_ ${ suffix } ` ] = salesUSD / qty - costPrice
row [ ` gross_profit_base_usd_ ${ suffix } ` ] = salesUSD - qty * basePrice
row [ ` gross_profit_cost_usd_ ${ suffix } ` ] = salesUSD - qty * costPrice
row [ ` gross_profit_usd_ ${ suffix } ` ] = row [ ` gross_profit_cost_usd_ ${ suffix } ` ]
} else {
row [ ` unit_profit_base_ ${ suffix } ` ] = 0
row [ ` unit_profit_cost_ ${ suffix } ` ] = 0
row [ ` gross_profit_base_usd_ ${ suffix } ` ] = 0
row [ ` gross_profit_cost_usd_ ${ suffix } ` ] = 0
row [ ` gross_profit_usd_ ${ suffix } ` ] = 0
}
row [ ` gross_margin_base_ ${ suffix } ` ] = marginFromSalesCost ( salesUSD , qty , basePrice )
row [ ` gross_margin_cost_ ${ suffix } ` ] = marginFromSalesCost ( salesUSD , qty , costPrice )
}
function stockTurnover ( salesQty , stockQty ) {
const stock = Number ( stockQty || 0 )
if ( stock <= 0 ) return 0
@@ -4461,11 +4555,21 @@ function formatProductCell (row, name) {
case 'gross_profit_usd_90d' :
case 'gross_profit_usd_180d' :
case 'gross_profit_usd_total' :
case 'gross_profit_base_usd_90d' :
case 'gross_profit_cost_usd_90d' :
case 'gross_profit_base_usd_180d' :
case 'gross_profit_cost_usd_180d' :
case 'gross_profit_base_usd_365d' :
case 'gross_profit_cost_usd_365d' :
case 'gross_profit_base_usd_total' :
case 'gross_profit_cost_usd_total' :
return formatMoney ( row [ name ] , 'USD' )
case 'gross_margin_base_90d' :
case 'gross_margin_cost_90d' :
case 'gross_margin_base_180d' :
case 'gross_margin_cost_180d' :
case 'gross_margin_base_365d' :
case 'gross_margin_cost_365d' :
case 'gross_margin_base_total' :
case 'gross_margin_cost_total' :
case 'gross_margin_90d' :
@@ -5045,7 +5149,7 @@ async function loadBackendGroupedRows (options = {}) {
function normalizeGroupedDisplayRow ( tabKey , row ) {
const nextRow = { ... row }
normalizeGroupedProductHierarchyValues ( nextRow )
return nextRow
return withPeriodScores ( withGeneralMargins ( withProductMargins ( nextRow ) ) )
}
function normalizeGroupedProductHierarchyValues ( row ) {