Merge remote-tracking branch 'origin/master'

This commit is contained in:
M_Kececi
2026-06-18 12:28:05 +03:00
parent e14c1c176a
commit a3d143ad70
14 changed files with 5123 additions and 21 deletions

View File

@@ -254,8 +254,14 @@ func ExportAllProductPricingHandler(w http.ResponseWriter, r *http.Request) {
}
rows = filterProductPricingExportRows(rows, parseProductPricingExportFilters(r))
currencies := parseExportCurrencies(r.URL.Query().Get("currencies"))
content := buildProductPricingExportCSV(rows, currencies)
priceFields := parseExportPriceFields(r.URL.Query().Get("price_fields"))
var content string
if len(priceFields) > 0 {
content = buildProductPricingExportCSVWithPriceFields(rows, priceFields)
} else {
currencies := parseExportCurrencies(r.URL.Query().Get("currencies"))
content = buildProductPricingExportCSV(rows, currencies)
}
filename := fmt.Sprintf("product_pricing_all_%s.csv", time.Now().Format("2006-01-02"))
w.Header().Set("Content-Type", "text/csv; charset=utf-8")
@@ -402,6 +408,39 @@ func parseExportCurrencies(raw string) []string {
return out
}
func parseExportPriceFields(raw string) []string {
requested := splitCSVParam(raw)
if len(requested) == 0 {
return nil
}
out := make([]string, 0, 18)
seen := map[string]bool{}
for _, item := range requested {
v := strings.ToLower(strings.TrimSpace(item))
if v == "" {
continue
}
// Accept both "usd1" and "USD1" etc.
switch v {
case "usd1", "usd2", "usd3", "usd4", "usd5", "usd6",
"eur1", "eur2", "eur3", "eur4", "eur5", "eur6",
"try1", "try2", "try3", "try4", "try5", "try6":
// ok
default:
continue
}
if seen[v] {
continue
}
seen[v] = true
out = append(out, v)
}
if len(out) == 0 {
return nil
}
return out
}
func matchesProductPricingValueFilters(row models.ProductPricing, filters map[string][]string) bool {
if len(filters) == 0 {
return true
@@ -509,7 +548,60 @@ func csvFloat(value float64) string {
return fmt.Sprintf("%.2f", value)
}
func buildProductPricingExportCSV(rows []models.ProductPricing, currencies []string) string {
func exportPriceFieldTitle(field string) string {
field = strings.ToLower(strings.TrimSpace(field))
if len(field) != 4 {
return strings.ToUpper(field)
}
cur := strings.ToUpper(field[:3])
lv := field[3:]
return fmt.Sprintf("%s %s", cur, lv)
}
func exportPriceFieldValue(row models.ProductPricing, field string) float64 {
switch strings.ToLower(strings.TrimSpace(field)) {
case "usd1":
return row.USD1
case "usd2":
return row.USD2
case "usd3":
return row.USD3
case "usd4":
return row.USD4
case "usd5":
return row.USD5
case "usd6":
return row.USD6
case "eur1":
return row.EUR1
case "eur2":
return row.EUR2
case "eur3":
return row.EUR3
case "eur4":
return row.EUR4
case "eur5":
return row.EUR5
case "eur6":
return row.EUR6
case "try1":
return row.TRY1
case "try2":
return row.TRY2
case "try3":
return row.TRY3
case "try4":
return row.TRY4
case "try5":
return row.TRY5
case "try6":
return row.TRY6
default:
return 0
}
}
func buildProductPricingExportCSVWithPriceFields(rows []models.ProductPricing, priceFields []string) string {
var b strings.Builder
headers := []string{
@@ -536,14 +628,12 @@ func buildProductPricingExportCSV(rows []models.ProductPricing, currencies []str
b.WriteString(csvEscape(h))
b.WriteString(";")
}
for idx, cur := range currencies {
for tier := 1; tier <= 6; tier++ {
b.WriteString(csvEscape(fmt.Sprintf("%s %d", cur, tier)))
if idx == len(currencies)-1 && tier == 6 {
b.WriteString("\n")
} else {
b.WriteString(";")
}
for i, pf := range priceFields {
b.WriteString(csvEscape(exportPriceFieldTitle(pf)))
if i == len(priceFields)-1 {
b.WriteString("\n")
} else {
b.WriteString(";")
}
}
@@ -572,15 +662,12 @@ func buildProductPricingExportCSV(rows []models.ProductPricing, currencies []str
b.WriteString(csvEscape(item))
b.WriteString(";")
}
for idx, cur := range currencies {
values := productPricingCurrencyValues(row, cur)
for tierIdx, value := range values {
b.WriteString(csvEscape(csvFloat(value)))
if idx == len(currencies)-1 && tierIdx == len(values)-1 {
b.WriteString("\n")
} else {
b.WriteString(";")
}
for i, pf := range priceFields {
b.WriteString(csvEscape(csvFloat(exportPriceFieldValue(row, pf))))
if i == len(priceFields)-1 {
b.WriteString("\n")
} else {
b.WriteString(";")
}
}
}
@@ -588,6 +675,26 @@ func buildProductPricingExportCSV(rows []models.ProductPricing, currencies []str
return b.String()
}
func buildProductPricingExportCSV(rows []models.ProductPricing, currencies []string) string {
// Backward compatible export: USD/EUR/TRY and all 1..6 tiers per currency.
fields := make([]string, 0, 18)
for _, cur := range currencies {
cur = strings.ToUpper(strings.TrimSpace(cur))
switch cur {
case "USD", "EUR", "TRY":
default:
continue
}
for lv := 1; lv <= 6; lv++ {
fields = append(fields, strings.ToLower(fmt.Sprintf("%s%d", cur, lv)))
}
}
if len(fields) == 0 {
fields = []string{"usd1", "usd2", "usd3", "usd4", "usd5", "usd6", "eur1", "eur2", "eur3", "eur4", "eur5", "eur6", "try1", "try2", "try3", "try4", "try5", "try6"}
}
return buildProductPricingExportCSVWithPriceFields(rows, fields)
}
func productPricingCurrencyValues(row models.ProductPricing, currency string) []float64 {
switch currency {
case "USD":