diff --git a/internal/entity/license.go b/internal/entity/license.go index e7301b0..8d0a7a2 100644 --- a/internal/entity/license.go +++ b/internal/entity/license.go @@ -6,17 +6,20 @@ import ( ) type License struct { - ID uuid.UUID `gorm:"type:uuid;primaryKey;default:uuid_generate_v4()"` - PartnerID int64 `gorm:"type:bigint;not null"` - Name string `gorm:"type:varchar(255);not null"` - StartDate time.Time `gorm:"type:date;not null"` - EndDate time.Time `gorm:"type:date;not null"` - RenewalDate *time.Time `gorm:"type:date"` - SerialNumber string `gorm:"type:varchar(255);unique;not null"` - CreatedBy int64 `gorm:"type:bigint;not null"` - UpdatedBy int64 `gorm:"type:bigint;not null"` - CreatedAt time.Time `gorm:"autoCreateTime"` - UpdatedAt time.Time `gorm:"autoUpdateTime"` + ID uuid.UUID `gorm:"type:uuid;primaryKey;default:uuid_generate_v4()"` + PartnerID int64 `gorm:"type:bigint;not null"` + Name string `gorm:"type:varchar(255);not null"` + StartDate time.Time `gorm:"type:date;not null"` + EndDate time.Time `gorm:"type:date;not null"` + RenewalDate *time.Time `gorm:"type:date"` + SerialNumber string `gorm:"type:varchar(255);unique;not null"` + CreatedBy int64 `gorm:"type:bigint;not null"` + UpdatedBy int64 `gorm:"type:bigint;not null"` + CreatedAt time.Time `gorm:"autoCreateTime"` + UpdatedAt time.Time `gorm:"autoUpdateTime"` + PartnerName string `gorm:"type:varchar(255);not null"` + LicenseStatus string `gorm:"type:string(255);not null"` + CreatedByName string `gorm:"type:string(255);not null"` } func (License) TableName() string { diff --git a/internal/handlers/http/license/license.go b/internal/handlers/http/license/license.go index 505169e..9a296bb 100644 --- a/internal/handlers/http/license/license.go +++ b/internal/handlers/http/license/license.go @@ -4,6 +4,7 @@ import ( "furtuna-be/internal/common/errors" "furtuna-be/internal/handlers/request" "furtuna-be/internal/handlers/response" + "furtuna-be/internal/middlewares" "furtuna-be/internal/services" "github.com/gin-gonic/gin" "github.com/go-playground/validator/v10" @@ -16,11 +17,12 @@ type Handler struct { func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) { route := group.Group("/license") + isAdmin := middlewares.IsAdminMiddleware() - route.POST("/", jwt, h.Create) - route.GET("/", jwt, h.GetAll) - route.PUT("/:id", jwt, h.Update) - route.GET("/:id", jwt, h.GetByID) + route.POST("/", jwt, isAdmin, h.Create) + route.GET("/", jwt, isAdmin, h.GetAll) + route.PUT("/:id", jwt, isAdmin, h.Update) + route.GET("/:id", jwt, isAdmin, h.GetByID) } func NewHandler(service services.License) *Handler { @@ -115,7 +117,9 @@ func (h *Handler) GetAll(c *gin.Context) { return } - licenses, total, err := h.service.GetAll(c.Request.Context(), req.Limit, req.Offset) + ctx := request.GetMyContext(c) + + licenses, total, err := h.service.GetAll(ctx, req.Limit, req.Offset, req.Status) if err != nil { response.ErrorWrapper(c, err) return diff --git a/internal/handlers/request/license.go b/internal/handlers/request/license.go index 499522c..9cffefb 100644 --- a/internal/handlers/request/license.go +++ b/internal/handlers/request/license.go @@ -17,8 +17,9 @@ type License struct { } type LicenseParam struct { - Limit int `form:"limit,default=10"` - Offset int `form:"offset,default=0"` + Limit int `form:"limit,default=10"` + Offset int `form:"offset,default=0"` + Status string `form:"status,default="` } func (r *License) ToEntity() (*entity.License, error) { diff --git a/internal/handlers/response/license.go b/internal/handlers/response/license.go index 4977991..f72196c 100644 --- a/internal/handlers/response/license.go +++ b/internal/handlers/response/license.go @@ -12,8 +12,10 @@ type License struct { RenewalDate string `json:"renewal_date,omitempty"` SerialNumber string `json:"serial_number"` PartnerID int64 `json:"partner_id"` - CreatedBy int64 `json:"created_by"` + CreatedBy string `json:"created_by"` UpdatedBy int64 `json:"updated_by"` + PartnerName string `json:"partner_name"` + Status string `json:"status"` } type LicenseList struct { @@ -33,8 +35,10 @@ func (r *License) FromEntity(e *entity.License) { } r.SerialNumber = e.SerialNumber r.PartnerID = e.PartnerID - r.CreatedBy = e.CreatedBy + r.CreatedBy = e.CreatedByName r.UpdatedBy = e.UpdatedBy + r.PartnerName = e.PartnerName + r.Status = e.LicenseStatus } func FromEntityList(entities []*entity.License) []License { diff --git a/internal/middlewares/auth.go b/internal/middlewares/auth.go index 40a3b65..8aed227 100644 --- a/internal/middlewares/auth.go +++ b/internal/middlewares/auth.go @@ -61,3 +61,23 @@ func SuperAdminMiddleware() gin.HandlerFunc { c.Next() } } + +func IsAdminMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + ctx, exists := c.Get("myCtx") + if !exists { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) + c.Abort() + return + } + + myCtx, ok := ctx.(*mycontext.MyContextImpl) + if !ok || !myCtx.IsAdmin() { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) + c.Abort() + return + } + + c.Next() + } +} diff --git a/internal/repository/license/license.go b/internal/repository/license/license.go index a4e568b..0f5e8fe 100644 --- a/internal/repository/license/license.go +++ b/internal/repository/license/license.go @@ -49,16 +49,36 @@ func (r *LicenseRepository) FindByID(ctx context.Context, id string) (*entity.Li return license, nil } -func (r *LicenseRepository) GetAll(ctx context.Context, limit, offset int) ([]*entity.License, int64, error) { +func (r *LicenseRepository) GetAll(ctx context.Context, limit, offset int, statusFilter string) ([]*entity.License, int64, error) { var licenses []*entity.License var total int64 - if err := r.db.WithContext(ctx). + // Define the main query with status calculation + 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 '< 30 days' + ELSE 'Active' + END as license_status, + 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"). Limit(limit). - Offset(offset). - Find(&licenses). - Count(&total). - Error; err != nil { + Offset(offset) + + // Wrap the main query as a subquery to filter by status + query := r.db.Table("(?) as sub", subQuery) + if statusFilter != "" { + query = query.Where("license_status = ?", statusFilter) + } + + if err := query.Find(&licenses).Error; err != nil { + return nil, 0, err + } + + if err := r.db.Table("licenses").Count(&total).Error; err != nil { return nil, 0, err } diff --git a/internal/repository/repository.go b/internal/repository/repository.go index 7db70ca..0d550ed 100644 --- a/internal/repository/repository.go +++ b/internal/repository/repository.go @@ -196,5 +196,5 @@ type License interface { Create(ctx context.Context, license *entity.LicenseDB) (*entity.LicenseDB, error) Update(ctx context.Context, license *entity.LicenseDB) (*entity.LicenseDB, error) FindByID(ctx context.Context, id string) (*entity.LicenseDB, error) - GetAll(ctx context.Context, limit, offset int) ([]*entity.License, int64, error) + GetAll(ctx context.Context, limit, offset int, statusFilter string) ([]*entity.License, int64, error) } diff --git a/internal/services/license/license.go b/internal/services/license/license.go index 7d94e4f..2e7bc54 100644 --- a/internal/services/license/license.go +++ b/internal/services/license/license.go @@ -61,8 +61,8 @@ func (s *LicenseService) GetByID(ctx context.Context, id string) (*entity.Licens return licenseDB.ToLicense(), nil } -func (s *LicenseService) GetAll(ctx context.Context, limit, offset int) ([]*entity.License, int64, error) { - licenses, total, err := s.repo.GetAll(ctx, limit, offset) +func (s *LicenseService) GetAll(ctx context.Context, limit, offset int, status string) ([]*entity.License, int64, error) { + licenses, total, err := s.repo.GetAll(ctx, limit, offset, status) if err != nil { logger.ContextLogger(ctx).Error("error when getting all licenses", zap.Error(err)) return nil, 0, err diff --git a/internal/services/service.go b/internal/services/service.go index 76450fa..3f3f15c 100644 --- a/internal/services/service.go +++ b/internal/services/service.go @@ -134,5 +134,5 @@ type License interface { Create(ctx mycontext.Context, licenseReq *entity.License) (*entity.License, error) Update(ctx mycontext.Context, id string, licenseReq *entity.License) (*entity.License, error) GetByID(ctx context.Context, id string) (*entity.License, error) - GetAll(ctx context.Context, limit, offset int) ([]*entity.License, int64, error) + GetAll(ctx context.Context, limit, offset int, status string) ([]*entity.License, int64, error) }