diff --git a/internal/services/export.go b/internal/services/export.go index 7606da9..cbed3cf 100644 --- a/internal/services/export.go +++ b/internal/services/export.go @@ -504,29 +504,30 @@ func (s *ExportService) resolveCategories(pricelistID *uint, lotNames []string) return categories } -// defaultCategoryOrder returns a category code → display_order map built from models.DefaultCategories. +// defaultCategoryOrder returns an uppercase category code → display_order map from models.DefaultCategories. func defaultCategoryOrder() map[string]int { m := make(map[string]int, len(models.DefaultCategories)) for _, cat := range models.DefaultCategories { - m[cat.Code] = cat.DisplayOrder + m[strings.ToUpper(cat.Code)] = cat.DisplayOrder } return m } +func categoryDisplayOrder(categoryOrder map[string]int, category string) (int, bool) { + order, ok := categoryOrder[strings.ToUpper(strings.TrimSpace(category))] + return order, ok +} + // sortItemsByCategory sorts items by category display order (items without category go to the end). func sortItemsByCategory(items []ExportItem, categoryOrder map[string]int) { - for i := 0; i < len(items)-1; i++ { - for j := i + 1; j < len(items); j++ { - orderI, hasI := categoryOrder[items[i].Category] - orderJ, hasJ := categoryOrder[items[j].Category] - - if !hasI && hasJ { - items[i], items[j] = items[j], items[i] - } else if hasI && hasJ && orderI > orderJ { - items[i], items[j] = items[j], items[i] - } + sort.SliceStable(items, func(i, j int) bool { + orderI, hasI := categoryDisplayOrder(categoryOrder, items[i].Category) + orderJ, hasJ := categoryDisplayOrder(categoryOrder, items[j].Category) + if hasI && hasJ { + return orderI < orderJ } - } + return hasI && !hasJ + }) } type pricingLevels struct {