Files
Novault-backend/internal/models/default_category.go

107 lines
3.3 KiB
Go
Raw Normal View History

package models
import (
"time"
"gorm.io/gorm"
)
// DefaultCategory represents a category template for new user initialization
// These templates are copied to users' categories table when they first access categories
type DefaultCategory struct {
ID uint `gorm:"primarykey" json:"id"`
Name string `gorm:"size:50;not null" json:"name"`
Icon string `gorm:"size:100" json:"icon"` // Iconify format: mdi:icon-name
Color string `gorm:"size:20" json:"color"` // HEX color code (e.g., #FF6B35)
Type CategoryType `gorm:"size:20;not null" json:"type"` // income or expense
ParentID *uint `gorm:"index" json:"parent_id,omitempty"`
SortOrder int `gorm:"default:0" json:"sort_order"`
IsActive bool `gorm:"default:true" json:"is_active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// Relationships
Parent *DefaultCategory `gorm:"foreignKey:ParentID" json:"parent,omitempty"`
Children []DefaultCategory `gorm:"foreignKey:ParentID" json:"children,omitempty"`
}
// TableName specifies the table name for DefaultCategory
func (DefaultCategory) TableName() string {
return "default_categories"
}
// GetAllDefaultCategories retrieves all active default categories from the database
func GetAllDefaultCategories(db *gorm.DB) ([]DefaultCategory, error) {
var categories []DefaultCategory
err := db.Where("is_active = ?", true).Order("sort_order ASC").Find(&categories).Error
return categories, err
}
// GetDefaultCategoriesWithChildren retrieves all active root categories with their children
func GetDefaultCategoriesWithChildren(db *gorm.DB) ([]DefaultCategory, error) {
var categories []DefaultCategory
err := db.Where("is_active = ? AND parent_id IS NULL", true).
Preload("Children", "is_active = ?", true).
Order("sort_order ASC").
Find(&categories).Error
return categories, err
}
// CopyToUserCategories copies default categories to a user's categories
// Returns a map of old DefaultCategory ID to new Category ID for parent-child mapping
func CopyDefaultCategoriesToUser(db *gorm.DB, userID uint) error {
// Get all default categories
var defaults []DefaultCategory
if err := db.Where("is_active = ?", true).Order("sort_order ASC").Find(&defaults).Error; err != nil {
return err
}
if len(defaults) == 0 {
return nil // No default categories to copy
}
// Map to track old ID -> new ID for parent references
idMap := make(map[uint]uint)
// First pass: create all root categories (no parent)
for _, dc := range defaults {
if dc.ParentID == nil {
cat := Category{
UserID: userID,
Name: dc.Name,
Icon: dc.Icon,
Color: dc.Color,
Type: dc.Type,
ParentID: nil,
SortOrder: dc.SortOrder,
}
if err := db.Create(&cat).Error; err != nil {
return err
}
idMap[dc.ID] = cat.ID
}
}
// Second pass: create all child categories
for _, dc := range defaults {
if dc.ParentID != nil {
newParentID := idMap[*dc.ParentID]
cat := Category{
UserID: userID,
Name: dc.Name,
Icon: dc.Icon,
Color: dc.Color,
Type: dc.Type,
ParentID: &newParentID,
SortOrder: dc.SortOrder,
}
if err := db.Create(&cat).Error; err != nil {
return err
}
idMap[dc.ID] = cat.ID
}
}
return nil
}