package license import ( "context" "furtuna-be/internal/common/logger" "furtuna-be/internal/entity" "github.com/google/uuid" "go.uber.org/zap" "gorm.io/gorm" ) type LicenseRepository struct { db *gorm.DB } func NewLicenseRepository(db *gorm.DB) *LicenseRepository { return &LicenseRepository{ db: db, } } func (r *LicenseRepository) Create(ctx context.Context, license *entity.LicenseDB) (*entity.LicenseDB, error) { if err := r.db.WithContext(ctx).Create(license).Error; err != nil { logger.ContextLogger(ctx).Error("error when creating license", zap.Error(err)) return nil, err } return license, nil } func (r *LicenseRepository) Update(ctx context.Context, license *entity.LicenseDB) (*entity.LicenseDB, error) { if err := r.db.WithContext(ctx).Save(license).Error; err != nil { logger.ContextLogger(ctx).Error("error when updating license", zap.Error(err)) return nil, err } return license, nil } func (r *LicenseRepository) FindByID(ctx context.Context, id string) (*entity.LicenseDB, error) { licenseID, err := uuid.Parse(id) if err != nil { return nil, err } license := new(entity.LicenseDB) if err := r.db.WithContext(ctx).First(license, licenseID).Error; err != nil { logger.ContextLogger(ctx).Error("error when finding license by ID", zap.Error(err)) return nil, err } return license, nil } func (r *LicenseRepository) GetAll(ctx context.Context, limit, offset int, statusFilter string) ([]*entity.LicenseGetAll, int64, error) { var licenses []*entity.LicenseGetAll var total int64 // Define the main query with status calculation and days to expire subQuery := r.db.WithContext(ctx). Table("licenses"). Select(`licenses.*, partners.name as partner_name, CASE WHEN licenses.end_date < CURRENT_DATE THEN 'EXPIRED' WHEN licenses.end_date < CURRENT_DATE + INTERVAL '30 days' THEN 'EXPIRING_SOON' ELSE 'ACTIVE' END as license_status, (GREATEST(licenses.end_date - CURRENT_DATE, 0)) as days_to_expire, users.name as created_by_name`). Joins("LEFT JOIN partners ON licenses.partner_id = partners.id"). Joins("LEFT JOIN users ON licenses.created_by = users.id") // Wrap the main query as a subquery to filter by status and apply pagination query := r.db.Table("(?) as sub", subQuery) if statusFilter != "" { query = query.Where("license_status = ?", statusFilter) } if limit > 0 { query = query.Limit(limit) } if offset > 0 { query = query.Offset(offset) } if err := query.Find(&licenses).Error; err != nil { return nil, 0, err } // Get the total count of records matching the filter countQuery := r.db.Table("(?) as sub", subQuery) if statusFilter != "" { countQuery = countQuery.Where("license_status = ?", statusFilter) } if err := countQuery.Count(&total).Error; err != nil { return nil, 0, err } return licenses, total, nil } func (r *LicenseRepository) FindByPartnerIDMaxEndDate(ctx context.Context, partnerID *int64) (*entity.LicenseDB, error) { var licenseDB entity.LicenseDB if err := r.db.Debug().WithContext(ctx). Where("partner_id = ?", partnerID). Order("end_date DESC"). First(&licenseDB).Error; err != nil { return nil, err } return &licenseDB, nil }