@@ -26,7 +26,7 @@ type productPerformanceExcelExportRequest struct {
type productPerformanceExcelColumn struct {
Header string
Kind string
Value func ( models . ProductPerformanceRow , models . ProductPerformanceGeneralRow , productPerformanceExcelStats ) any
Value func ( * productPerformanceExcelVariant , productPerformanceExcelStats ) any
}
type productPerformanceExcelStats struct {
@@ -36,6 +36,52 @@ type productPerformanceExcelStats struct {
AvgSalesUSDTotal float64
}
type productPerformanceExcelVariant struct {
KpiDate string
ProductCode string
ColorCode string
ColorDescription string
YakaKodu string
ItemDescription string
Kategori string
Seri string
YasGrubu string
AskiliYan string
UrunIlkGrubu string
UrunAnaGrubu string
UrunAltGrubu string
StockQty float64
BasePriceUSD float64
CostPriceUSD float64
SalesQty90 float64
SalesQty180 float64
SalesQty365 float64
SalesUSD90 float64
SalesUSD180 float64
SalesUSD365 float64
SalesQtyTotalProduct float64
SalesUSDTotalProduct float64
SalesQtyTotalGeneral float64
SalesUSDTotalGeneral float64
HasGeneralTotal bool
MarketCount90 int
CustomerCount90 int
MarketCountTotal int
CustomerCountTotal int
Markets90 map [ string ] bool
MarketsTotal map [ string ] bool
MarketFiltered bool
PerformanceBucket string
Recommendation string
LastSaleDate string
LastRefNumber string
UpdatedAt string
}
func ExportProductPerformanceExcelHandler ( pg * sql . DB ) http . HandlerFunc {
return func ( w http . ResponseWriter , r * http . Request ) {
traceID := utils . TraceIDFromRequest ( r )
@@ -50,7 +96,7 @@ func ExportProductPerformanceExcelHandler(pg *sql.DB) http.HandlerFunc {
}
}
rows , _ , err := queries . ListProductPerformance ( ctx , pg , queries . ProductPerformanceFilters {
productRows , _ , err := queries . ListProductPerformance ( ctx , pg , queries . ProductPerformanceFilters {
Limit : 50000 ,
Page : 1 ,
SortBy : "product_code" ,
@@ -66,13 +112,12 @@ func ExportProductPerformanceExcelHandler(pg *sql.DB) http.HandlerFunc {
http . Error ( w , "urun performans genel excel listesi alinamadi: " + err . Error ( ) , http . StatusInternalServerError )
return
}
generalByKey := productPerformanceExcelGeneralMap ( generalRows )
rows = filterProductPerformanceExcelRows ( rows , generalByKey , req . Filters )
sortProductPerformanceExcelRows ( rows , generalByKey , req . SortBy , req . Descending == nil || * req . Descending )
stats := productPerformanceExcelStatsFor ( rows , generalByKey )
rows := buildProductPerformanceExcelVariants ( productRows , generalRows , req . Filters )
sortProductPerformanceExcelVariants ( rows , req . SortBy , req . Descending == nil || * req . Descending )
stats := productPerformanceExcelStatsFor ( rows )
file , err := buildProductPerformanceExcelFile ( rows , generalByKey , stats )
file , err := buildProductPerformanceExcelFile ( rows , stats )
if err != nil {
http . Error ( w , "urun performans excel dosyasi hazirlanamadi: " + err . Error ( ) , http . StatusInternalServerError )
return
@@ -85,7 +130,7 @@ func ExportProductPerformanceExcelHandler(pg *sql.DB) http.HandlerFunc {
return
}
filename := fmt . Sprintf ( "product_performance_color _yaka_%s.xlsx" , time . Now ( ) . Format ( "20060102_150405" ) )
filename := fmt . Sprintf ( "product_performance_renk _yaka_%s.xlsx" , time . Now ( ) . Format ( "20060102_150405" ) )
w . Header ( ) . Set ( "Content-Type" , "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" )
w . Header ( ) . Set ( "Content-Disposition" , "attachment; filename=\"" + filename + "\"" )
w . Header ( ) . Set ( "Content-Length" , fmt . Sprint ( len ( buf . Bytes ( ) ) ) )
@@ -94,7 +139,158 @@ func ExportProductPerformanceExcelHandler(pg *sql.DB) http.HandlerFunc {
}
}
func buildProductPerformanceExcelFile ( rows [ ] models . ProductPerformanceRow , generalByKey map [ string ] models . ProductPerformanceGeneralRow , stats productPerformanceExcelStats ) ( * excelize . File , error ) {
func buildProductPerformanceExcelVariants ( productRows [ ] models . ProductPerformanceRow , generalRows [ ] models . ProductPerformanceGeneralRow , filters map [ string ] [ ] string ) [ ] * productPerformanceExcelVariant {
byKey := map [ string ] * productPerformanceExcelVariant { }
marketFiltered := productPerformanceExcelHasFilter ( filters , "market_key" )
for _ , row := range productRows {
if ! productPerformanceExcelProductRowMatchesFilters ( row , filters ) {
continue
}
key := productPerformanceExcelVariantKey ( row . ProductCode , row . ColorCode , row . YakaKodu )
v := byKey [ key ]
if v == nil {
v = & productPerformanceExcelVariant { Markets90 : map [ string ] bool { } , MarketsTotal : map [ string ] bool { } , MarketFiltered : marketFiltered }
byKey [ key ] = v
}
v . addProductRow ( row )
}
for _ , row := range generalRows {
if ! productPerformanceExcelGeneralRowMatchesFilters ( row , filters ) {
continue
}
key := productPerformanceExcelVariantKey ( row . ProductCode , row . ColorCode , row . YakaKodu )
v := byKey [ key ]
if v == nil {
v = & productPerformanceExcelVariant { Markets90 : map [ string ] bool { } , MarketsTotal : map [ string ] bool { } , MarketFiltered : marketFiltered }
byKey [ key ] = v
}
v . addGeneralRow ( row )
}
out := make ( [ ] * productPerformanceExcelVariant , 0 , len ( byKey ) )
for _ , row := range byKey {
if productPerformanceExcelVariantMatchesPostFilters ( row , filters ) {
out = append ( out , row )
}
}
return out
}
func ( v * productPerformanceExcelVariant ) addProductRow ( row models . ProductPerformanceRow ) {
v . fillDimensions (
row . KpiDate , row . ProductCode , row . ColorCode , row . ColorDescription , row . YakaKodu , row . ItemDescription ,
row . Kategori , row . Seri , row . YasGrubu , row . AskiliYan , row . UrunIlkGrubu , row . UrunAnaGrubu , row . UrunAltGrubu ,
row . BasePriceUSD , row . CostPriceUSD , row . StockQty , row . LastSaleDate , row . LastRefNumber , row . UpdatedAt ,
)
v . SalesQty90 += row . SalesQty90
v . SalesQty180 += row . SalesQty180
v . SalesQty365 += row . SalesQty365
v . SalesUSD90 += row . SalesUSD90
v . SalesUSD180 += row . SalesUSD180
v . SalesUSD365 += row . SalesUSD365
v . SalesQtyTotalProduct += row . SalesQtyTotal
v . SalesUSDTotalProduct += row . SalesUSDTotal
v . MarketCount90 = productPerformanceExcelMaxInt ( v . MarketCount90 , row . MarketCount90 )
if row . SalesUSD90 > 0 {
v . CustomerCount90 += row . CustomerCount90
}
v . PerformanceBucket = productPerformanceExcelFirstNonEmpty ( v . PerformanceBucket , row . PerformanceBucket )
v . Recommendation = productPerformanceExcelFirstNonEmpty ( v . Recommendation , row . Recommendation )
v . addMarket ( row . MarketKey , row . SalesQty90 , row . SalesUSD90 , row . SalesQtyTotal , row . SalesUSDTotal )
}
func ( v * productPerformanceExcelVariant ) addGeneralRow ( row models . ProductPerformanceGeneralRow ) {
v . fillDimensions (
productPerformanceExcelFirstNonEmpty ( row . PeriodEnd , row . PeriodStart ) , row . ProductCode , row . ColorCode , row . ColorDescription , row . YakaKodu , row . ItemDescription ,
row . Kategori , row . Seri , row . YasGrubu , row . AskiliYan , row . UrunIlkGrubu , row . UrunAnaGrubu , row . UrunAltGrubu ,
row . BasePriceUSD , row . CostPriceUSD , row . StockQty , row . LastSaleDate , row . LastRefNumber , "" ,
)
v . SalesQtyTotalGeneral += row . SalesQtyTotal
v . SalesUSDTotalGeneral += row . SalesUSDTotal
v . HasGeneralTotal = true
v . MarketCountTotal = productPerformanceExcelMaxInt ( v . MarketCountTotal , row . MarketCountTotal )
if row . SalesUSDTotal > 0 {
v . CustomerCountTotal += row . CustomerCountTotal
}
v . PerformanceBucket = productPerformanceExcelFirstNonEmpty ( v . PerformanceBucket , row . PerformanceBucket )
v . Recommendation = productPerformanceExcelFirstNonEmpty ( v . Recommendation , row . Recommendation )
v . addMarket ( row . MarketKey , 0 , 0 , row . SalesQtyTotal , row . SalesUSDTotal )
}
func ( v * productPerformanceExcelVariant ) fillDimensions ( kpiDate , productCode , colorCode , colorDescription , yakaKodu , itemDescription , kategori , seri , yasGrubu , askiliYan , urunIlkGrubu , urunAnaGrubu , urunAltGrubu string , basePrice , costPrice , stockQty float64 , lastSaleDate , lastRefNumber , updatedAt string ) {
v . KpiDate = productPerformanceExcelFirstNonEmpty ( v . KpiDate , kpiDate )
v . ProductCode = productPerformanceExcelFirstNonEmpty ( v . ProductCode , productCode )
v . ColorCode = productPerformanceExcelFirstNonEmpty ( v . ColorCode , colorCode )
v . ColorDescription = productPerformanceExcelFirstNonEmpty ( v . ColorDescription , colorDescription )
v . YakaKodu = productPerformanceExcelFirstNonEmpty ( v . YakaKodu , yakaKodu )
v . ItemDescription = productPerformanceExcelFirstNonEmpty ( v . ItemDescription , itemDescription )
v . Kategori = productPerformanceExcelFirstNonEmpty ( v . Kategori , kategori )
v . Seri = productPerformanceExcelFirstNonEmpty ( v . Seri , seri )
v . YasGrubu = productPerformanceExcelFirstNonEmpty ( v . YasGrubu , yasGrubu )
v . AskiliYan = productPerformanceExcelFirstNonEmpty ( v . AskiliYan , productPerformanceExcelCleanOptional ( askiliYan ) )
v . UrunIlkGrubu = productPerformanceExcelFirstNonEmpty ( v . UrunIlkGrubu , productPerformanceExcelCleanOptional ( urunIlkGrubu ) )
v . UrunAnaGrubu = productPerformanceExcelFirstNonEmpty ( v . UrunAnaGrubu , urunAnaGrubu )
v . UrunAltGrubu = productPerformanceExcelFirstNonEmpty ( v . UrunAltGrubu , urunAltGrubu )
v . BasePriceUSD = productPerformanceExcelFirstNonZero ( v . BasePriceUSD , basePrice )
v . CostPriceUSD = productPerformanceExcelFirstNonZero ( v . CostPriceUSD , costPrice )
if stockQty > v . StockQty {
v . StockQty = stockQty
}
if lastSaleDate > v . LastSaleDate {
v . LastSaleDate = lastSaleDate
v . LastRefNumber = lastRefNumber
}
if updatedAt > v . UpdatedAt {
v . UpdatedAt = updatedAt
}
}
func ( v * productPerformanceExcelVariant ) addMarket ( marketKey string , salesQty90 , salesUSD90 , salesQtyTotal , salesUSDTotal float64 ) {
market := productPerformanceExcelMarketName ( marketKey )
if market == "" || market == "STOK" {
return
}
if salesUSD90 > 0 {
v . Markets90 [ market ] = true
}
if salesUSDTotal > 0 {
v . MarketsTotal [ market ] = true
}
}
func ( v * productPerformanceExcelVariant ) totalQty ( ) float64 {
if v . HasGeneralTotal {
return v . SalesQtyTotalGeneral
}
return v . SalesQtyTotalProduct
}
func ( v * productPerformanceExcelVariant ) totalUSD ( ) float64 {
if v . HasGeneralTotal {
return v . SalesUSDTotalGeneral
}
return v . SalesUSDTotalProduct
}
func ( v * productPerformanceExcelVariant ) marketCount90 ( ) int {
if v . MarketFiltered {
return len ( v . Markets90 )
}
return productPerformanceExcelMaxInt ( v . MarketCount90 , len ( v . Markets90 ) )
}
func ( v * productPerformanceExcelVariant ) marketCountTotal ( ) int {
if v . MarketFiltered {
return len ( v . MarketsTotal )
}
return productPerformanceExcelMaxInt ( v . MarketCountTotal , len ( v . MarketsTotal ) )
}
func ( v * productPerformanceExcelVariant ) marketsLabel ( ) string {
return productPerformanceExcelSortedSetLabel ( v . MarketsTotal )
}
func buildProductPerformanceExcelFile ( rows [ ] * productPerformanceExcelVariant , stats productPerformanceExcelStats ) ( * excelize . File , error ) {
f := excelize . NewFile ( )
sheet := "RenkYaka"
f . SetSheetName ( "Sheet1" , sheet )
@@ -121,350 +317,200 @@ func buildProductPerformanceExcelFile(rows []models.ProductPerformanceRow, gener
for rowIndex , row := range rows {
excelRow := rowIndex + 2
general := generalByKey [ productPerformanceExcelVariantKey ( row . ProductCode , row . ColorCode , row . YakaKodu ) ]
for colIndex , col := range columns {
cell , _ := excelize . CoordinatesToCellName ( colIndex + 1 , excelRow )
value := col . Value ( row , general , stats )
switch col . Kind {
case "text" :
value := col . Value ( row , stats )
if col . Kind == "text" {
_ = f . SetCellStr ( sheet , cell , strings . TrimSpace ( fmt . Sprint ( value ) ) )
default :
} else {
_ = f . SetCellValue ( sheet , cell , productPerformanceExcelFloat ( value ) )
}
}
}
lastRow := len ( rows ) + 1
lastRow := productPerformanceExcelMaxInt ( len ( rows ) + 1 , 2 )
if len ( columns ) > 0 {
filterLastRow := lastRow
if filterLastRow < 2 {
filterLastRow = 2
}
lastFilterCell , _ := excelize . CoordinatesToCellName ( len ( columns ) , filterLastRow )
lastFilterCell , _ := excelize . CoordinatesToCellName ( len ( columns ) , lastRow )
_ = f . AutoFilter ( sheet , "A1:" + lastFilterCell , [ ] excelize . AutoFilterOptions { } )
}
for i , col := range columns {
colName , _ := excelize . ColumnNumberToName ( i + 1 )
width := productPerformanceExcelColumnWidth ( col . Header , col . Kind )
_ = f . SetColWidth ( sheet , colName , colName , width )
if lastRow >= 2 {
style := decimalStyle
switch col . Kind {
case "tex t" :
style = textStyle
case "i nt" :
style = intStyle
case "percent" :
style = percentStyle
}
_ = f . SetCellStyle ( sheet , fmt . Sprintf ( "%s2" , colName ) , fmt . Sprintf ( "%s%d" , colName , lastRow ) , style )
_ = f . SetColWidth ( sheet , colName , colName , productPerformanceExcelColumnWidth ( col . Header , col . Kind ) )
style := decimalStyle
switch col . Kind {
case "text" :
style = textStyle
case "in t" :
style = intStyle
case "perce nt" :
style = percentStyle
}
_ = f . SetCellStyle ( sheet , fmt . Sprintf ( "%s2" , colName ) , fmt . Sprintf ( "%s%d" , colName , lastRow ) , style )
}
_ = f . SetPanes ( sheet , & excelize . Panes {
Freeze : true ,
Split : false ,
XSplit : 0 ,
YSplit : 1 ,
TopLeftCell : "A2" ,
ActivePane : "bottomLeft" ,
} )
_ = f . SetPanes ( sheet , & excelize . Panes { Freeze : true , YSplit : 1 , TopLeftCell : "A2" , ActivePane : "bottomLeft" } )
return f , nil
}
func productPerformanceExcelColumns ( ) [ ] productPerformanceExcelColumn {
base := [ ] productPerformanceExcelColumn {
textExcelColumn ( "KPI Tarihi" , func ( v * productPerformanceExcelVariant ) any { return v . KpiDate } ) ,
textExcelColumn ( "Ürün İlk Grubu" , func ( v * productPerformanceExcelVariant ) any { return v . UrunIlkGrubu } ) ,
textExcelColumn ( "Askı lı /Yan" , func ( v * productPerformanceExcelVariant ) any { return v . AskiliYan } ) ,
textExcelColumn ( "Kategori" , func ( v * productPerformanceExcelVariant ) any { return v . Kategori } ) ,
textExcelColumn ( "Ürün Ana Grubu" , func ( v * productPerformanceExcelVariant ) any { return v . UrunAnaGrubu } ) ,
textExcelColumn ( "Ürün Alt Grubu" , func ( v * productPerformanceExcelVariant ) any { return v . UrunAltGrubu } ) ,
textExcelColumn ( "Ürün" , func ( v * productPerformanceExcelVariant ) any { return v . ProductCode } ) ,
textExcelColumn ( "Açıklama" , func ( v * productPerformanceExcelVariant ) any { return v . ItemDescription } ) ,
textExcelColumn ( "Renk" , func ( v * productPerformanceExcelVariant ) any { return v . ColorCode } ) ,
textExcelColumn ( "Renk Açıklama" , func ( v * productPerformanceExcelVariant ) any { return v . ColorDescription } ) ,
textExcelColumn ( "Yaka" , func ( v * productPerformanceExcelVariant ) any { return v . YakaKodu } ) ,
textExcelColumn ( "Renk/Yaka" , func ( v * productPerformanceExcelVariant ) any {
return productPerformanceExcelColorYaka ( v . ColorCode , v . ColorDescription , v . YakaKodu )
} ) ,
textExcelColumn ( "Piyasalar" , func ( v * productPerformanceExcelVariant ) any { return v . marketsLabel ( ) } ) ,
numberExcelColumn ( "Toplam Stok" , "int" , func ( v * productPerformanceExcelVariant ) any { return v . StockQty } ) ,
}
base = append ( base , productPerformanceExcelPeriodColumns ( "90G" , "90d" , func ( v * productPerformanceExcelVariant ) ( float64 , float64 , int , int ) {
return v . SalesQty90 , v . SalesUSD90 , v . marketCount90 ( ) , v . CustomerCount90
} ) ... )
base = append ( base , productPerformanceExcelPeriodColumns ( "180G" , "180d" , func ( v * productPerformanceExcelVariant ) ( float64 , float64 , int , int ) {
return v . SalesQty180 , v . SalesUSD180 , v . marketCount90 ( ) , v . CustomerCount90
} ) ... )
base = append ( base , productPerformanceExcelPeriodColumns ( "360G" , "365d" , func ( v * productPerformanceExcelVariant ) ( float64 , float64 , int , int ) {
return v . SalesQty365 , v . SalesUSD365 , v . marketCount90 ( ) , v . CustomerCount90
} ) ... )
base = append ( base , productPerformanceExcelPeriodColumns ( "Genel" , "total" , func ( v * productPerformanceExcelVariant ) ( float64 , float64 , int , int ) {
return v . totalQty ( ) , v . totalUSD ( ) , v . marketCountTotal ( ) , v . CustomerCountTotal
} ) ... )
base = append ( base ,
textExcelColumn ( "Durum" , func ( v * productPerformanceExcelVariant ) any { return productPerformanceExcelStatus ( v ) } ) ,
textExcelColumn ( "Öneri" , func ( v * productPerformanceExcelVariant ) any { return productPerformanceExcelRecommendation ( v ) } ) ,
textExcelColumn ( "Son Satış" , func ( v * productPerformanceExcelVariant ) any { return v . LastSaleDate } ) ,
textExcelColumn ( "Son Ref" , func ( v * productPerformanceExcelVariant ) any { return v . LastRefNumber } ) ,
textExcelColumn ( "Güncelleme" , func ( v * productPerformanceExcelVariant ) any { return v . UpdatedAt } ) ,
)
return base
}
func productPerformanceExcelPeriodColumns ( label , suffix string , values func ( * productPerformanceExcelVariant ) ( float64 , float64 , int , int ) ) [ ] productPerformanceExcelColumn {
return [ ] productPerformanceExcelColumn {
{ Header : "KPI Tarihi" , Kind : "tex t", Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . KpiDate
} } ,
{ Header : "Ürün İlk Grubu" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelCleanOptional ( r . UrunIlkGrubu )
} } ,
{ Header : "Askı lı /Yan" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelCleanOptional ( r . AskiliYan )
} } ,
{ Header : "Kategori" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . Kategori
} } ,
{ Header : "Ürün Ana Grubu" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . UrunAnaGrubu
} } ,
{ Header : "Ürün Alt Grubu" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . UrunAltGrubu
} } ,
{ Header : "Ürün" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . ProductCode
} } ,
{ Header : "Açıklama" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . ItemDescription
} } ,
{ Header : "Renk" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . ColorCode
} } ,
{ Header : "Renk Açıklama" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . ColorDescription
} } ,
{ Header : "Yaka" , Kind : "tex t", Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . YakaKodu
} } ,
{ Header : "Renk/Yaka" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelColorYaka ( r )
} } ,
{ Header : "Toplam Stok" , Kind : "int" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . StockQty
} } ,
{ Header : "90G Toplam Adet" , Kind : "int" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . SalesQty90
} } ,
{ Header : "90G Toplam Ciro USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . SalesUSD90
} } ,
{ Header : "90G Ağ. Ort. Fiyat USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelAvgPrice ( r . SalesUSD90 , r . SalesQty90 )
} } ,
{ Header : "90G Ağ. Ort. Stok Gün" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . StockDays90
} } ,
{ Header : "90G Stok Devir" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonZero ( r . StockTurnover90 , productPerformanceExcelStockTurnover ( r . SalesQty90 , r . StockQty ) )
} } ,
{ Header : "90G Ort. Taban Maliyet USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . BasePriceUSD
} } ,
{ Header : "90G Ort. Çıplak Maliyet USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . CostPriceUSD
} } ,
{ Header : "90G Ağ. Ort. Birim Taban K/Z USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelUnitProfit ( r . SalesUSD90 , r . SalesQty90 , r . BasePriceUSD )
} } ,
{ Header : "90G Ağ. Ort. Birim Çıplak K/Z USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelUnitProfit ( r . SalesUSD90 , r . SalesQty90 , r . CostPriceUSD )
} } ,
{ Header : "90G Taban Toplam K/Z USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelGrossProfit ( r . SalesUSD90 , r . SalesQty90 , r . BasePriceUSD )
} } ,
{ Header : "90G Çıplak Toplam K/Z USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelGrossProfit ( r . SalesUSD90 , r . SalesQty90 , r . CostPriceUSD )
} } ,
{ Header : "90G Taban Marj" , Kind : "percent" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelMargin ( r . SalesUSD90 , r . SalesQty90 , r . BasePriceUSD )
} } ,
{ Header : "90G Çıplak Marj" , Kind : "percent" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelMargin ( r . SalesUSD90 , r . SalesQty90 , r . CostPriceUSD )
} } ,
{ Header : "90G Tekil Piyasa" , Kind : "int" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . MarketCount90
} } ,
{ Header : "90G Tekil Müşteri" , Kind : "int" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . CustomerCount90
} } ,
{ Header : "90G Endeks" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , stats productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonZero ( r . SalesIndex90 , productPerformanceExcelRelativeIndex ( r . SalesUSD90 , stats . AvgSalesUSD90 ) )
} } ,
{ Header : "90G Ürün Skor" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , stats productPerformanceExcelStats ) any {
if strings . TrimSpace ( r . PerformanceBucket ) != "" {
return r . PerformanceScore
}
return productPerformanceExcelProductScore ( "90d" , r . SalesUSD90 , productPerformanceExcelRelativeIndex ( r . SalesUSD90 , stats . AvgSalesUSD90 ) , productPerformanceExcelMargin ( r . SalesUSD90 , r . SalesQty90 , r . CostPriceUSD ) , productPerformanceExcelStockTurnover ( r . SalesQty90 , r . StockQty ) , float64 ( r . MarketCount90 ) , float64 ( r . CustomerCount90 ) )
} } ,
{ Header : "180G Toplam Adet" , Kind : "int" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . SalesQty180
} } ,
{ Header : "180G Toplam Ciro USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . SalesUSD180
} } ,
{ Header : "180G Ağ. Ort. Fiyat USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelAvgPrice ( r . SalesUSD180 , r . SalesQty180 )
} } ,
{ Header : "180G Ağ. Ort. Stok Gün" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . StockDays180
} } ,
{ Header : "180G Stok Devir" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonZero ( r . StockTurnover180 , productPerformanceExcelStockTurnover ( r . SalesQty180 , r . StockQty ) )
} } ,
{ Header : "180G Ort. Taban Maliyet USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . BasePriceUSD
} } ,
{ Header : "180G Ort. Çıplak Maliyet USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . CostPriceUSD
} } ,
{ Header : "180G Taban Toplam K/Z USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelGrossProfit ( r . SalesUSD180 , r . SalesQty180 , r . BasePriceUSD )
} } ,
{ Header : "180G Çıplak Toplam K/Z USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelGrossProfit ( r . SalesUSD180 , r . SalesQty180 , r . CostPriceUSD )
} } ,
{ Header : "180G Taban Marj" , Kind : "percent" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelMargin ( r . SalesUSD180 , r . SalesQty180 , r . BasePriceUSD )
} } ,
{ Header : "180G Çıplak Marj" , Kind : "percent" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelMargin ( r . SalesUSD180 , r . SalesQty180 , r . CostPriceUSD )
} } ,
{ Header : "180G Ürün Skor" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , stats productPerformanceExcelStats ) any {
return productPerformanceExcelProductScore ( "180d" , r . SalesUSD180 , productPerformanceExcelRelativeIndex ( r . SalesUSD180 , stats . AvgSalesUSD180 ) , productPerformanceExcelMargin ( r . SalesUSD180 , r . SalesQty180 , r . CostPriceUSD ) , productPerformanceExcelStockTurnover ( r . SalesQty180 , r . StockQty ) , productPerformanceExcelFirstNonZero ( float64 ( g . MarketCountTotal ) , float64 ( r . MarketCount90 ) ) , productPerformanceExcelFirstNonZero ( float64 ( g . CustomerCountTotal ) , float64 ( r . CustomerCount90 ) ) )
} } ,
{ Header : "360G Toplam Adet" , Kind : "int" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . SalesQty365
} } ,
{ Header : "360G Toplam Ciro USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . SalesUSD365
} } ,
{ Header : "360G Ağ. Ort. Fiyat USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelAvgPrice ( r . SalesUSD365 , r . SalesQty365 )
} } ,
{ Header : "360G Ağ. Ort. Stok Gün" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . StockDays365
} } ,
{ Header : "360G Stok Devir" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonZero ( r . StockTurnover365 , productPerformanceExcelStockTurnover ( r . SalesQty365 , r . StockQty ) )
} } ,
{ Header : "360G Ort. Taban Maliyet USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . BasePriceUSD
} } ,
{ Header : "360G Ort. Çıplak Maliyet USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . CostPriceUSD
} } ,
{ Header : "360G Taban Toplam K/Z USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelGrossProfit ( r . SalesUSD365 , r . SalesQty365 , r . BasePriceUSD )
} } ,
{ Header : "360G Çıplak Toplam K/Z USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelGrossProfit ( r . SalesUSD365 , r . SalesQty365 , r . CostPriceUSD )
} } ,
{ Header : "360G Taban Marj" , Kind : "percent" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelMargin ( r . SalesUSD365 , r . SalesQty365 , r . BasePriceUSD )
} } ,
{ Header : "360G Çıplak Marj" , Kind : "percent" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelMargin ( r . SalesUSD365 , r . SalesQty365 , r . CostPriceUSD )
} } ,
{ Header : "360G Ürün Skor" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , stats productPerformanceExcelStats ) any {
return productPerformanceExcelProductScore ( "365d" , r . SalesUSD365 , productPerformanceExcelRelativeIndex ( r . SalesUSD365 , stats . AvgSalesUSD365 ) , productPerformanceExcelMargin ( r . SalesUSD365 , r . SalesQty365 , r . CostPriceUSD ) , productPerformanceExcelStockTurnover ( r . SalesQty365 , r . StockQty ) , productPerformanceExcelFirstNonZero ( float64 ( g . MarketCountTotal ) , float64 ( r . MarketCount90 ) ) , productPerformanceExcelFirstNonZero ( float64 ( g . CustomerCountTotal ) , float64 ( r . CustomerCount90 ) ) )
} } ,
{ Header : "Genel Toplam Adet" , Kind : "int" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelTotalSalesQty ( r , g )
} } ,
{ Header : "Genel Toplam Ciro USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelTotalSalesUSD ( r , g )
} } ,
{ Header : "Genel Ağ. Ort. Fiyat USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonZero ( g . AvgPriceUSDTotal , productPerformanceExcelAvgPrice ( productPerformanceExcelTotalSalesUSD ( r , g ) , productPerformanceExcelTotalSalesQty ( r , g ) ) )
} } ,
{ Header : "Genel Ağ. Ort. Stok Gün" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonZero ( g . StockDaysTotal , r . StockDaysTotal )
} } ,
{ Header : "Genel Stok Devir" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonZero ( r . StockTurnoverTotal , productPerformanceExcelStockTurnover ( productPerformanceExcelTotalSalesQty ( r , g ) , r . StockQty ) )
} } ,
{ Header : "Genel Ort. Taban Maliyet USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonZero ( g . BasePriceUSD , r . BasePriceUSD )
} } ,
{ Header : "Genel Ort. Çıplak Maliyet USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonZero ( g . CostPriceUSD , r . CostPriceUSD )
} } ,
{ Header : "Genel Taban Toplam K/Z USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelGrossProfit ( productPerformanceExcelTotalSalesUSD ( r , g ) , productPerformanceExcelTotalSalesQty ( r , g ) , productPerformanceExcelFirstNonZero ( g . BasePriceUSD , r . BasePriceUSD ) )
} } ,
{ Header : "Genel Çıplak Toplam K/Z USD" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelGrossProfit ( productPerformanceExcelTotalSalesUSD ( r , g ) , productPerformanceExcelTotalSalesQty ( r , g ) , productPerformanceExcelFirstNonZero ( g . CostPriceUSD , r . CostPriceUSD ) )
} } ,
{ Header : "Genel Taban Marj" , Kind : "percent" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelMargin ( productPerformanceExcelTotalSalesUSD ( r , g ) , productPerformanceExcelTotalSalesQty ( r , g ) , productPerformanceExcelFirstNonZero ( g . BasePriceUSD , r . BasePriceUSD ) )
} } ,
{ Header : "Genel Çıplak Marj" , Kind : "percent" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelMargin ( productPerformanceExcelTotalSalesUSD ( r , g ) , productPerformanceExcelTotalSalesQty ( r , g ) , productPerformanceExcelFirstNonZero ( g . CostPriceUSD , r . CostPriceUSD ) )
} } ,
{ Header : "Genel Tekil Piyasa" , Kind : "int" , Value : func ( _ models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return g . MarketCountTotal
} } ,
{ Header : "Genel Tekil Müşteri" , Kind : "int" , Value : func ( _ models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return g . CustomerCountTotal
} } ,
{ Header : "Genel Fatura" , Kind : "int" , Value : func ( _ models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return g . InvoiceCountTotal
} } ,
{ Header : "Genel Endeks" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , stats productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonZero ( g . SalesIndexTotal , productPerformanceExcelRelativeIndex ( productPerformanceExcelTotalSalesUSD ( r , g ) , stats . AvgSalesUSDTotal ) )
} } ,
{ Header : "Genel Ürün Skor" , Kind : "number" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , stats productPerformanceExcelStats ) any {
if strings . TrimSpace ( g . PerformanceBucket ) != "" {
return g . PerformanceScore
}
return productPerformanceExcelProductScore ( "total" , productPerformanceExcelTotalSalesUSD ( r , g ) , productPerformanceExcelRelativeIndex ( productPerformanceExcelTotalSalesUSD ( r , g ) , stats . AvgSalesUSDTotal ) , productPerformanceExcelMargin ( productPerformanceExcelTotalSalesUSD ( r , g ) , productPerformanceExcelTotalSalesQty ( r , g ) , productPerformanceExcelFirstNonZero ( g . CostPriceUSD , r . CostPriceUSD ) ) , productPerformanceExcelStockTurnover ( productPerformanceExcelTotalSalesQty ( r , g ) , r . StockQty ) , float64 ( g . MarketCountTotal ) , float64 ( g . CustomerCountTotal ) )
} } ,
{ Header : "Durum" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelBucketLabel ( productPerformanceExcelFirstNonEmpty ( g . PerformanceBucket , r . PerformanceBucket ) )
} } ,
{ Header : "Öneri" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonEmpty ( g . Recommendation , r . Recommendation )
} } ,
{ Header : "Son Satış" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonEmpty ( g . LastSaleDate , r . LastSaleDate )
} } ,
{ Header : "Son Ref" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , g models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return productPerformanceExcelFirstNonEmpty ( g . LastRefNumber , r . LastRefNumber )
} } ,
{ Header : "Güncelleme" , Kind : "text" , Value : func ( r models . ProductPerformanceRow , _ models . ProductPerformanceGeneralRow , _ productPerformanceExcelStats ) any {
return r . UpdatedAt
} } ,
numberExcelColumn ( label + " Toplam Adet" , "in t", func ( v * productPerformanceExcelVariant ) any {
qty , _ , _ , _ := values ( v )
return qty
} ) ,
numberExcelColumn ( label + " Toplam Ciro USD" , "number" , func ( v * productPerformanceExcelVariant ) any {
_ , usd , _ , _ := values ( v )
return usd
} ) ,
numberExcelColumn ( label + " Ciro/Adet USD" , "number" , func ( v * productPerformanceExcelVariant ) any {
qty , usd , _ , _ := values ( v )
return productPerformanceExcelAvgPrice ( usd , qty )
} ) ,
numberExcelColumn ( label + " Satış/Stok Oranı " , "number" , func ( v * productPerformanceExcelVariant ) any {
qty , _ , _ , _ := values ( v )
return productPerformanceExcelStockTurnover ( qty , v . StockQty )
} ) ,
numberExcelColumn ( label + " Taban Maliyet USD" , "number" , func ( v * productPerformanceExcelVariant ) any { return v . BasePriceUSD } ) ,
numberExcelColumn ( label + " Çıplak Maliyet USD" , "number" , func ( v * productPerformanceExcelVariant ) any { return v . CostPriceUSD } ) ,
numberExcelColumn ( label + " Taban Toplam K/Z USD" , "number" , func ( v * productPerformanceExcelVariant ) any {
qty , usd , _ , _ := values ( v )
return productPerformanceExcelGrossProfit ( usd , qty , v . BasePriceUSD )
} ) ,
numberExcelColumn ( label + " Çıplak Toplam K/Z USD" , "number" , func ( v * productPerformanceExcelVariant ) any {
qty , usd , _ , _ := values ( v )
return productPerformanceExcelGrossProfit ( usd , qty , v . CostPriceUSD )
} ) ,
numberExcelColumn ( label + " Taban Marj" , "percent" , func ( v * productPerformanceExcelVariant ) any {
qty , usd , _ , _ := values ( v )
return productPerformanceExcelMargin ( usd , qty , v . BasePriceUSD )
} ) ,
numberExcelColumn ( label + " Çıplak Marj" , "percen t", func ( v * productPerformanceExcelVariant ) any {
qty , usd , _ , _ := values ( v )
return productPerformanceExcelMargin ( usd , qty , v . CostPriceUSD )
} ) ,
numberExcelColumn ( label + " Tekil Piyasa" , "int" , func ( v * productPerformanceExcelVariant ) any {
_ , _ , markets , _ := values ( v )
return markets
} ) ,
numberExcelColumn ( label + " Tekil Müşteri" , "int" , func ( v * productPerformanceExcelVariant ) any {
_ , _ , _ , customers := values ( v )
return customers
} ) ,
numberExcelColumn ( label + " Ürün Skor" , "number" , func ( v * productPerformanceExcelVariant ) any {
qty , usd , markets , customers := values ( v )
return productPerformanceExcelProductScore ( suffix , usd , productPerformanceExcelStockTurnover ( qty , v . StockQty ) , float64 ( markets ) , float64 ( customers ) , productPerformanceExcelMargin ( usd , qty , v . CostPriceUSD ) )
} ) ,
}
}
func productPerformanceExcelGeneralMap ( rows [ ] models . ProductPerformanceGeneralRow ) map [ string ] models . ProductPerformanceGeneralRow {
out := make ( map [ string ] models . ProductPerformanceGeneralRow , len ( rows ) )
for _ , row := range rows {
out [ productPerformanceExcelVariantKey ( row . ProductCode , row . ColorCode , row . YakaKodu ) ] = row
}
return out
func textExcelColumn ( header string , value func ( * productPerformanceExcelVariant ) any ) productPerformanceExcelColumn {
return productPerformanceExcelColumn { Header : header , Kind : "text" , Value : func ( v * productPerformanceExcelVariant , _ productPerformanceExcelStats ) any { return value ( v ) } }
}
func filterProductPerformanceExcelRows ( rows [ ] models . ProductPerformanceRow , generalByKey map [ string ] models . ProductPerformanceGeneralRow , filters map [ string ] [ ] string ) [ ] models . ProductPerformanceRow {
if len ( filters ) == 0 {
return rows
}
out := make ( [ ] models . ProductPerformanceRow , 0 , len ( rows ) )
for _ , row := range rows {
general := generalByKey [ productPerformanceExcelVariantKey ( row . ProductCode , row . ColorCode , row . YakaKodu ) ]
if productPerformanceExcelRowMatchesFilters ( row , general , filters ) {
out = append ( out , row )
}
}
return out
func numberExcelColumn ( header , kind string , value func ( * productPerformanceExcelVariant ) any ) productPerformanceExcelColumn {
return productPerformanceExcelColumn { Header : header , Kind : kind , Value : func ( v * productPerformanceExcelVariant , _ productPerformanceExcelStats ) any { return value ( v ) } }
}
func productPerformanceExcelRowMatchesFilters ( row models . ProductPerformanceRow , general models . ProductPerformanceGeneralRow , filters map [ string ] [ ] string ) bool {
for field , values := range filters {
selected : = productPerformanceExcelSelectedSet ( values )
if len ( selected ) == 0 {
func productPerformanceExcelProductRowMatchesFilters ( row models . ProductPerformanceRow , filters map [ string ] [ ] string ) bool {
for field , selected := range productPerformanceExcelFilterSets ( filters ) {
if field = = "performance_bucket" {
continue
}
matched := false
for _ , candidate := range productPerformanceExcelFilterCandidates ( row , general , field ) {
if selected [ productPerformanceExcelNormalize ( candidate ) ] {
matched = true
break
}
}
if ! matched {
if ! productPerformanceExcelMatchesAny ( selected , productPerformanceExcelProductFilterCandidates ( row , field ) ) {
return false
}
}
return true
}
func productPerformanceExcelSelectedSet ( values [ ] string ) map [ string ] bool {
out := make ( map [ string ] bool , len ( values ) )
for _ , value : = range values {
value = productPerformanceExcelNormalize ( value )
if value != "" {
out [ value ] = true
func productPerformanceExcelGeneralRowMatchesFilters ( row models . ProductPerformanceGeneralRow , filters map [ string ] [ ] string ) bool {
for field , selected := range productPerformanceExcelFilterSets ( filters ) {
if field = = "performance_bucket" {
continue
}
if ! productPerformanceExcelMatchesAny ( selected , productPerformanceExcelGeneralFilterCandidates ( row , field ) ) {
return false
}
}
return true
}
func productPerformanceExcelVariantMatchesPostFilters ( row * productPerformanceExcelVariant , filters map [ string ] [ ] string ) bool {
selected := productPerformanceExcelFilterSets ( filters ) [ "performance_bucket" ]
if len ( selected ) == 0 {
return true
}
return productPerformanceExcelMatchesAny ( selected , [ ] string { row . PerformanceBucket , productPerformanceExcelStatus ( row ) } )
}
func productPerformanceExcelFilterSets ( filters map [ string ] [ ] string ) map [ string ] map [ string ] bool {
out := map [ string ] map [ string ] bool { }
for field , values := range filters {
field = strings . TrimSpace ( field )
for _ , value := range values {
value = productPerformanceExcelNormalize ( value )
if value == "" {
continue
}
if out [ field ] == nil {
out [ field ] = map [ string ] bool { }
}
out [ field ] [ value ] = true
}
}
return out
}
func productPerformanceExcelFilterCandidates ( row models . ProductPerformanceRow , general models . ProductPerformanceGeneralRow , field string ) [ ] string {
func productPerformanceExcelHasFilter ( filters map [ string ] [ ] string , field string ) bool {
for _ , value := range filters [ strings . TrimSpace ( field ) ] {
if strings . TrimSpace ( value ) != "" {
return true
}
}
return false
}
func productPerformanceExcelProductFilterCandidates ( row models . ProductPerformanceRow , field string ) [ ] string {
switch strings . TrimSpace ( field ) {
case "product_code" :
return [ ] string { row . ProductCode }
@@ -475,7 +521,7 @@ func productPerformanceExcelFilterCandidates(row models.ProductPerformanceRow, g
case "yaka_kodu" :
return [ ] string { row . YakaKodu }
case "color_yaka" :
return [ ] string { productPerformanceExcelColorYaka ( row ) , row . ColorCode + "/" + row . YakaKodu }
return [ ] string { productPerformanceExcelColorYaka ( row . ColorCode , row . ColorDescription , row . YakaKodu ) , row . ColorCode + "/" + row . YakaKodu }
case "kategori" :
return [ ] string { row . Kategori }
case "askili_yan" :
@@ -483,33 +529,67 @@ func productPerformanceExcelFilterCandidates(row models.ProductPerformanceRow, g
case "urun_ilk_grubu" :
return [ ] string { productPerformanceExcelCleanOptional ( row . UrunIlkGrubu ) }
case "urun_ana_grubu" :
return [ ] string { productPerformanceExcelFirstNonEmpty ( general . UrunAnaGrubu , row . UrunAnaGrubu ) }
return [ ] string { row . UrunAnaGrubu }
case "urun_alt_grubu" :
return [ ] string { row . UrunAltGrubu }
case "market_key" :
return [ ] string { row . MarketKey , productPerformanceExcelMarketName ( row . MarketKey ) }
case "performance_bucket" :
bucket := productPerformanceExcelFirstNonEmpty ( general . PerformanceBucket , row . PerformanceBucket )
return [ ] string { bucket , productPerformanceExcelBucketLabel ( bucket ) }
default :
return nil
}
}
func sortProductPerformanceExcelRows ( rows [ ] models . ProductPerformanceRow , generalByKey map [ string ] models . ProductPerformanceGeneralRow , sortBy string , desc bool ) {
func productPerformanceExcelGeneralFilterCandidates ( row models . ProductPerformanceGeneralRow , field string ) [ ] string {
switch strings . TrimSpace ( field ) {
case "product_code" :
return [ ] string { row . ProductCode }
case "item_description" :
return [ ] string { row . ItemDescription }
case "color_code" :
return [ ] string { row . ColorCode }
case "yaka_kodu" :
return [ ] string { row . YakaKodu }
case "color_yaka" :
return [ ] string { productPerformanceExcelColorYaka ( row . ColorCode , row . ColorDescription , row . YakaKodu ) , row . ColorCode + "/" + row . YakaKodu }
case "kategori" :
return [ ] string { row . Kategori }
case "askili_yan" :
return [ ] string { productPerformanceExcelCleanOptional ( row . AskiliYan ) }
case "urun_ilk_grubu" :
return [ ] string { productPerformanceExcelCleanOptional ( row . UrunIlkGrubu ) }
case "urun_ana_grubu" :
return [ ] string { row . UrunAnaGrubu }
case "urun_alt_grubu" :
return [ ] string { row . UrunAltGrubu }
case "market_key" :
return [ ] string { row . MarketKey , productPerformanceExcelMarketName ( row . MarketKey ) }
default :
return nil
}
}
func productPerformanceExcelMatchesAny ( selected map [ string ] bool , candidates [ ] string ) bool {
if len ( selected ) == 0 {
return true
}
for _ , candidate := range candidates {
if selected [ productPerformanceExcelNormalize ( candidate ) ] {
return true
}
}
return false
}
func sortProductPerformanceExcelVariants ( rows [ ] * productPerformanceExcelVariant , sortBy string , desc bool ) {
sortBy = strings . TrimSpace ( sortBy )
if sortBy == "" || sortBy == "image" {
sortBy = "product_code"
desc = false
}
sort . SliceStable ( rows , func ( i , j int ) bool {
left := rows [ i ]
right := rows [ j ]
leftGen := generalByKey [ productPerformanceExcelVariantKey ( left . ProductCode , left . ColorCode , left . YakaKodu ) ]
rightGen := generalByKey [ productPerformanceExcelVariantKey ( right . ProductCode , right . ColorCode , right . YakaKodu ) ]
cmp := productPerformanceExcelCompareSort ( left , leftGen , right , rightGen , sortBy )
cmp := productPerformanceExcelCompare ( rows [ i ] , rows [ j ] , sortBy )
if cmp == 0 {
cmp = strings . Compare ( productPerformanceExcelHierarchySortKey ( left ) , productPerformanceExcelHierarchySortKey ( right ) )
cmp = strings . Compare ( productPerformanceExcelHierarchySortKey ( rows [ i ] ) , productPerformanceExcelHierarchySortKey ( rows [ j ] ) )
}
if desc {
return cmp > 0
@@ -518,20 +598,19 @@ func sortProductPerformanceExcelRows(rows []models.ProductPerformanceRow, genera
} )
}
func productPerformanceExcelCompareSort ( left models . ProductPerformanceRow , leftGen models . ProductPerformanceGeneralRow , right models . ProductPerformanceRow , rightGen models . ProductPerformanceGeneralRow , sortBy string ) int {
leftNum , rightNum , numeric := productPerformanceExcelSortNumeric ( left , leftGen , sortBy ) , productPerformanceExcelSortNumeric ( right , rightGen , sortBy ) , productPerformanceExcelIsNumericSort ( sortBy )
if numeric {
if leftNum < rightNum {
func productPerformanceExcelCompare ( a , b * productPerformanceExcelVariant , sortBy string ) int {
if productPerformanceExcelIsNumericSort ( sortBy ) {
av := productPerformanceExcelSortNumber ( a , sortBy )
bv := productPerformanceExcelSortNumber ( b , sortBy )
if av < bv {
return - 1
}
if leftNum > rightNum {
if av > bv {
return 1
}
return 0
}
leftText := productPerformanceExcelSortText ( left , leftGen , sortBy )
rightText := productPerformanceExcelSortText ( right , rightGen , sortBy )
return strings . Compare ( productPerformanceExcelNormalize ( leftText ) , productPerformanceExcelNormalize ( rightText ) )
return strings . Compare ( productPerformanceExcelNormalize ( productPerformanceExcelSortText ( a , sortBy ) ) , productPerformanceExcelNormalize ( productPerformanceExcelSortText ( b , sortBy ) ) )
}
func productPerformanceExcelIsNumericSort ( sortBy string ) bool {
@@ -539,17 +618,16 @@ func productPerformanceExcelIsNumericSort(sortBy string) bool {
case "stock_qty" , "sales_qty_90d" , "sales_qty_180d" , "sales_qty_365d" , "sales_qty_total" ,
"sales_usd_90d" , "sales_usd_180d" , "sales_usd_365d" , "sales_usd_total" ,
"avg_price_usd_90d" , "avg_price_usd_180d" , "avg_price_usd_365d" , "avg_price_usd_total" ,
"stock_days_90d" , "stock_days_180d" , "stock_days_365d" , "stock_days_total" ,
"stock_turnover_90d" , "stock_turnover_180d" , "stock_turnover_365d" , "stock_turnover_total" ,
"base_price_usd" , "cost_price_usd" , "market_count_90d" , "customer_count_90d" , "market_count_total" , "customer_count_total" ,
"sales_index_90d" , "sales_index_total" , " performance_score", "performance_score_90d" , "performance_score_total" :
"performance_score" , "performance_score_90d" , "performance_score_total" :
return true
default :
return false
}
}
func productPerformanceExcelSortNumeric ( row models . ProductPerformanceRow , general models . ProductPerformanceGeneralRow , sortBy string ) float64 {
func productPerformanceExcelSortNumber ( row * productPerformanceExcelVariant , sortBy string ) float64 {
switch sortBy {
case "stock_qty" :
return row . StockQty
@@ -560,7 +638,7 @@ func productPerformanceExcelSortNumeric(row models.ProductPerformanceRow, genera
case "sales_qty_365d" :
return row . SalesQty365
case "sales_qty_total" :
return productPerformanceExcelTotalSalesQty ( row , general )
return row . totalQty ( )
case "sales_usd_90d" :
return row . SalesUSD90
case "sales_usd_180d" :
@@ -568,7 +646,7 @@ func productPerformanceExcelSortNumeric(row models.ProductPerformanceRow, genera
case "sales_usd_365d" :
return row . SalesUSD365
case "sales_usd_total" :
return productPerformanceExcelTotalSalesUSD ( row , general )
return row . totalUSD ( )
case "avg_price_usd_90d" :
return productPerformanceExcelAvgPrice ( row . SalesUSD90 , row . SalesQty90 )
case "avg_price_usd_180d" :
@@ -576,54 +654,42 @@ func productPerformanceExcelSortNumeric(row models.ProductPerformanceRow, genera
case "avg_price_usd_365d" :
return productPerformanceExcelAvgPrice ( row . SalesUSD365 , row . SalesQty365 )
case "avg_price_usd_total" :
return productPerformanceExcelFirstNonZero ( general . AvgPriceUSDTotal , productPerformanceExcelAvgPrice ( productPerformanceExcelTotalSalesUSD ( row , general ) , productPerformanceExcelTotalSalesQty ( row , general ) ) )
case "stock_days_90d" :
return row . StockDays90
case "stock_days_180d" :
return row . StockDays180
case "stock_days_365d" :
return row . StockDays365
case "stock_days_total" :
return productPerformanceExcelFirstNonZero ( general . StockDaysTotal , row . StockDaysTotal )
return productPerformanceExcelAvgPrice ( row . totalUSD ( ) , row . totalQty ( ) )
case "stock_turnover_90d" :
return row . StockTurnover90
return productPerformanceExcelStockTurnover ( row . SalesQty90 , row . StockQty )
case "stock_turnover_180d" :
return row . StockTurnover180
return productPerformanceExcelStockTurnover ( row . SalesQty180 , row . StockQty )
case "stock_turnover_365d" :
return row . StockTurnover365
return productPerformanceExcelStockTurnover ( row . SalesQty365 , row . StockQty )
case "stock_turnover_total" :
return row . StockTurnoverTotal
return productPerformanceExcelStockTurnover ( row . totalQty ( ) , row . StockQty )
case "base_price_usd" :
return productPerformanceExcelFirstNonZero ( general . BasePriceUSD , row . BasePriceUSD )
return row . BasePriceUSD
case "cost_price_usd" :
return productPerformanceExcelFirstNonZero ( general . CostPriceUSD , row . CostPriceUSD )
return row . CostPriceUSD
case "market_count_90d" :
return float64 ( row . MarketCount90 )
return float64 ( row . marketCount90 ( ) )
case "customer_count_90d" :
return float64 ( row . CustomerCount90 )
case "market_count_total" :
return float64 ( general . MarketCountTotal )
return float64 ( row . marketCountTotal ( ) )
case "customer_count_total" :
return float64 ( general . CustomerCountTotal )
case "sales_index_90d" :
return row . SalesIndex90
case "sales_index_total" :
return general . SalesIndexTotal
return float64 ( row . CustomerCountTotal )
case "performance_score" , "performance_score_90d" :
return row . PerformanceScore
return productPerformanceExcelProductScore ( "90d" , row . SalesUSD90 , productPerformanceExcelStockTurnover ( row . SalesQty90 , row . StockQty ) , float64 ( row . marketCount90 ( ) ) , float64 ( row . CustomerCount90 ) , productPerformanceExcelMargin ( row . SalesUSD90 , row . SalesQty90 , row . CostPriceUSD ) )
case "performance_score_total" :
return general . PerformanceScore
return productPerformanceExcelProductScore ( "total" , row . totalUSD ( ) , productPerformanceExcelStockTurnover ( row . totalQty ( ) , row . StockQty ) , float64 ( row . marketCountTotal ( ) ) , float64 ( row . CustomerCountTotal ) , productPerformanceExcelMargin ( row . totalUSD ( ) , row . totalQty ( ) , row . CostPriceUSD ) )
default :
return 0
}
}
func productPerformanceExcelSortText ( row models . ProductPerformanceRow , general models . ProductPerformanceGeneralRow , sortBy string ) string {
func productPerformanceExcelSortText ( row * productPerformanceExcelVariant , sortBy string ) string {
switch sortBy {
case "product_code" :
return row . ProductCode
case "color_yaka" :
return productPerformanceExcelColorYaka ( row )
return productPerformanceExcelColorYaka ( row . ColorCode , row . ColorDescription , row . YakaKodu )
case "color_code" :
return row . ColorCode
case "yaka_kodu" :
@@ -633,40 +699,26 @@ func productPerformanceExcelSortText(row models.ProductPerformanceRow, general m
case "kategori" :
return row . Kategori
case "askili_yan" :
return productPerformanceExcelCleanOptional ( row . AskiliYan )
return row . AskiliYan
case "urun_ilk_grubu" :
return productPerformanceExcelCleanOptional ( row . UrunIlkGrubu )
return row . UrunIlkGrubu
case "urun_ana_grubu" :
return productPerformanceExcelFirstNonEmpty ( general . UrunAnaGrubu , row . UrunAnaGrubu )
return row . UrunAnaGrubu
case "urun_alt_grubu" :
return row . UrunAltGrubu
case "market_key" :
return productPerformanceExcelMarketName ( row . MarketKey )
return row . marketsLabel ( )
case "performance_bucket" :
return productPerformanceExcelBucketLabel ( productPerformanceExcelFirstNonEmpty ( general . PerformanceBucket , row . PerformanceBucket ) )
return productPerformanceExcelStatus ( row )
default :
return productPerformanceExcelHierarchySortKey ( row )
}
}
func productPerformanceExcelHierarchySortKey ( row models . ProductPerformanceRow ) string {
return strings . Join ( [ ] string {
productPerformanceExcelCleanOptional ( row . UrunIlkGrubu ) ,
productPerformanceExcelCleanOptional ( row . AskiliYan ) ,
row . Kategori ,
row . UrunAnaGrubu ,
row . UrunAltGrubu ,
row . ProductCode ,
row . ColorCode ,
row . YakaKodu ,
} , "|" )
}
func productPerformanceExcelStatsFor ( rows [ ] models . ProductPerformanceRow , generalByKey map [ string ] models . ProductPerformanceGeneralRow ) productPerformanceExcelStats {
func productPerformanceExcelStatsFor ( rows [ ] * productPerformanceExcelVariant ) productPerformanceExcelStats {
var stats productPerformanceExcelStats
var c90 , c180 , c365 , cTotal float64
for _ , row := range rows {
general := generalByKey [ productPerformanceExcelVariantKey ( row . ProductCode , row . ColorCode , row . YakaKodu ) ]
if row . SalesUSD90 > 0 {
stats . AvgSalesUSD90 += row . SalesUSD90
c90 ++
@@ -679,8 +731,8 @@ func productPerformanceExcelStatsFor(rows []models.ProductPerformanceRow, genera
stats . AvgSalesUSD365 += row . SalesUSD365
c365 ++
}
if total := productPerformanceExcelTotalSalesUSD ( row , general ) ; total > 0 {
stats . AvgSalesUSDTotal += total
if row . totalUSD ( ) > 0 {
stats . AvgSalesUSDTotal += row . totalUSD ( )
cTotal ++
}
}
@@ -703,12 +755,16 @@ func productPerformanceExcelVariantKey(productCode, colorCode, yakaKodu string)
return strings . ToUpper ( strings . TrimSpace ( productCode ) ) + "|" + strings . ToUpper ( strings . TrimSpace ( colorCode ) ) + "|" + strings . ToUpper ( strings . TrimSpace ( yakaKodu ) )
}
func productPerformanceExcelColorYaka ( row models . ProductPerformanceRow ) string {
color := strings . TrimSpace ( row . ColorCode )
if desc := strings . TrimSpace ( row . ColorDescription ) ; color != "" && desc != "" {
func productPerformanceExcelHierarchySortKey ( row * productPerformanceExcelVariant ) string {
return strings . Join ( [ ] string { row . UrunIlkGrubu , row . AskiliYan , row . Kategori , row . UrunAnaGrubu , row . UrunAltGrubu , row . ProductCode , row . ColorCode , row . YakaKodu } , "|" )
}
func productPerformanceExcelColorYaka ( colorCode , colorDescription , yakaKodu string ) string {
color := strings . TrimSpace ( colorCode )
if desc := strings . TrimSpace ( colorDescription ) ; color != "" && desc != "" {
color = color + "-" + strings . ToUpper ( desc )
}
yaka := strings . TrimSpace ( row . YakaKodu )
yaka := strings . TrimSpace ( yakaKodu )
parts := make ( [ ] string , 0 , 2 )
if color != "" && color != "-" {
parts = append ( parts , color )
@@ -730,6 +786,34 @@ func productPerformanceExcelMarketName(value string) string {
return ""
}
func productPerformanceExcelStatus ( row * productPerformanceExcelVariant ) string {
switch {
case row . totalQty ( ) > 0 && row . totalUSD ( ) <= 0 :
return "Ciro/Fiyat Kontrol"
case row . totalQty ( ) <= 0 && row . StockQty > 0 :
return "Stok Riski"
case productPerformanceExcelMargin ( row . totalUSD ( ) , row . totalQty ( ) , row . CostPriceUSD ) < 0 :
return "Fiyat Baskı sı "
case productPerformanceExcelProductScore ( "total" , row . totalUSD ( ) , productPerformanceExcelStockTurnover ( row . totalQty ( ) , row . StockQty ) , float64 ( row . marketCountTotal ( ) ) , float64 ( row . CustomerCountTotal ) , productPerformanceExcelMargin ( row . totalUSD ( ) , row . totalQty ( ) , row . CostPriceUSD ) ) >= 70 :
return "Yı ldı z Ürün"
default :
return productPerformanceExcelBucketLabel ( row . PerformanceBucket )
}
}
func productPerformanceExcelRecommendation ( row * productPerformanceExcelVariant ) string {
switch {
case row . totalQty ( ) > 0 && row . totalUSD ( ) <= 0 :
return "Satış adedi var ama USD ciro/fiyat yok. Satış tutarı aktarı mı ve döviz dönüşümü kontrol edilmeli."
case row . totalQty ( ) <= 0 && row . StockQty > 0 :
return "Satış yok, stok duruyor. Piyasa/fiyat aksiyonu gerekli."
case row . Recommendation != "" :
return row . Recommendation
default :
return "Düzenli takip."
}
}
func productPerformanceExcelBucketLabel ( value string ) string {
switch strings . TrimSpace ( value ) {
case "YILDIZ_URUN" :
@@ -782,16 +866,8 @@ func productPerformanceExcelFirstNonZero(values ...float64) float64 {
return 0
}
func productPerformanceExcelTotalSalesQty ( row models . ProductPerformanceRow , general models . ProductPerformanceGeneralRow ) float64 {
return productPerformanceExcelFirstNonZero ( general . SalesQtyTotal , row . SalesQtyTotal )
}
func productPerformanceExcelTotalSalesUSD ( row models . ProductPerformanceRow , general models . ProductPerformanceGeneralRow ) float64 {
return productPerformanceExcelFirstNonZero ( general . SalesUSDTotal , row . SalesUSDTotal )
}
func productPerformanceExcelAvgPrice ( salesUSD , qty float64 ) float64 {
if qty = = 0 {
if qty < = 0 {
return 0
}
return salesUSD / qty
@@ -804,13 +880,6 @@ func productPerformanceExcelStockTurnover(salesQty, stockQty float64) float64 {
return salesQty / stockQty
}
func productPerformanceExcelUnitProfit ( salesUSD , qty , unitCost float64 ) float64 {
if qty <= 0 {
return 0
}
return ( salesUSD / qty ) - unitCost
}
func productPerformanceExcelGrossProfit ( salesUSD , qty , unitCost float64 ) float64 {
if qty <= 0 {
return 0
@@ -819,27 +888,20 @@ func productPerformanceExcelGrossProfit(salesUSD, qty, unitCost float64) float64
}
func productPerformanceExcelMargin ( salesUSD , qty , unitCost float64 ) float64 {
if salesUSD = = 0 {
if salesUSD < = 0 {
return 0
}
return productPerformanceExcelGrossProfit ( salesUSD , qty , unitCost ) / salesUSD
}
func productPerformanceExcelRelativeIndex ( value , average float64 ) float64 {
if value <= 0 || average <= 0 {
return 0
}
return value / average
}
func productPerformanceExcelProductScore ( suffix string , salesUSD , salesIndex , margin , stockTurnover , marketCount , customerCount float64 ) float64 {
revenue := productPerformanceExcelRatioScore ( salesIndex , 2 )
if revenue == 0 {
revenue = productPerformanceExcelRatioScore ( salesUSD , productPerformanceExcelProductRevenueTarget ( suffix ) )
func productPerformanceExcelProductScore ( suffix string , salesUSD , stockTurnover , marketCount , customerCount , margin float64 ) float64 {
if salesUSD <= 0 {
return 1
}
revenueScore := productPerformanceExcelRatioScore ( salesUSD , productPerformanceExcelProductRevenueTarget ( suffix ) )
score := 0.30 * productPerformanceExcelMarginScore ( margin ) +
0.20 * productPerformanceExcelRatioScore ( stockTurnover , 1.50 ) +
0.20 * revenue +
0.20 * revenueScore +
0.15 * productPerformanceExcelRatioScore ( marketCount , 8 ) +
0.15 * productPerformanceExcelRatioScore ( customerCount , 25 )
return productPerformanceExcelRoundScore ( score )
@@ -915,15 +977,36 @@ func productPerformanceExcelFloat(value any) float64 {
}
}
func productPerformanceExcelSortedSetLabel ( values map [ string ] bool ) string {
out := make ( [ ] string , 0 , len ( values ) )
for value := range values {
if strings . TrimSpace ( value ) != "" {
out = append ( out , value )
}
}
sort . Strings ( out )
return strings . Join ( out , ", " )
}
func productPerformanceExcelColumnWidth ( header , kind string ) float64 {
if kind == "text" {
if strings . Contains ( header , "Piyasalar" ) || strings . Contains ( header , "Öneri" ) {
return 34
}
if len ( [ ] rune ( header ) ) > 14 {
return 24
}
return 16
}
if strings . Contains ( header , "Marj" ) || strings . Contains ( header , "Skor" ) || strings . Contains ( header , "Endeks" ) {
if strings . Contains ( header , "Marj" ) || strings . Contains ( header , "Skor" ) {
return 14
}
return 16
}
func productPerformanceExcelMaxInt ( a , b int ) int {
if a > b {
return a
}
return b
}