MIF_E31222379_BE/internal/admin/approval_repository.go

184 lines
5.1 KiB
Go

package admin
import (
"context"
"fmt"
"rijig/model"
"strings"
"gorm.io/gorm"
)
type ApprovalRepository interface {
GetPendingUsers(ctx context.Context, req *GetPendingUsersRequest) ([]model.User, int64, error)
GetUserByID(ctx context.Context, userID string) (*model.User, error)
UpdateUserRegistrationStatus(ctx context.Context, userID, status string, progress int8) error
GetApprovalSummary(ctx context.Context) (*ApprovalSummary, error)
GetUsersByIDs(ctx context.Context, userIDs []string) ([]model.User, error)
BulkUpdateRegistrationStatus(ctx context.Context, userIDs []string, status string, progress int8) error
}
type approvalRepository struct {
db *gorm.DB
}
func NewApprovalRepository(db *gorm.DB) ApprovalRepository {
return &approvalRepository{
db: db,
}
}
func (r *approvalRepository) GetPendingUsers(ctx context.Context, req *GetPendingUsersRequest) ([]model.User, int64, error) {
var users []model.User
var totalRecords int64
query := r.db.WithContext(ctx).Model(&model.User{}).
Preload("Role").
Preload("IdentityCard").
Preload("CompanyProfile")
query = r.applyFilters(query, req)
if err := query.Count(&totalRecords).Error; err != nil {
return nil, 0, fmt.Errorf("failed to count pending users: %w", err)
}
offset := (req.Page - 1) * req.Limit
if err := query.
Order("created_at DESC").
Limit(req.Limit).
Offset(offset).
Find(&users).Error; err != nil {
return nil, 0, fmt.Errorf("failed to fetch pending users: %w", err)
}
return users, totalRecords, nil
}
func (r *approvalRepository) applyFilters(query *gorm.DB, req *GetPendingUsersRequest) *gorm.DB {
if req.Status != "" {
if req.Status == "pending" {
req.Status = "awaiting_approval"
}
query = query.Where("registration_status = ?", req.Status)
}
if req.Role != "" {
query = query.Joins("JOIN roles ON roles.id = users.role_id").
Where("LOWER(roles.role_name) = ?", strings.ToLower(req.Role))
}
query = query.Where("registration_progress >= ?", 2)
return query
}
func (r *approvalRepository) GetUserByID(ctx context.Context, userID string) (*model.User, error) {
var user model.User
if err := r.db.WithContext(ctx).
Preload("Role").
Preload("IdentityCard").
Preload("CompanyProfile").
Where("id = ?", userID).
First(&user).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, fmt.Errorf("user not found")
}
return nil, fmt.Errorf("failed to get user: %w", err)
}
return &user, nil
}
func (r *approvalRepository) UpdateUserRegistrationStatus(ctx context.Context, userID, status string, progress int8) error {
result := r.db.WithContext(ctx).
Model(&model.User{}).
Where("id = ?", userID).
Updates(map[string]interface{}{
"registration_status": status,
"registration_progress": progress,
"updated_at": "NOW()",
})
if result.Error != nil {
return fmt.Errorf("failed to update user registration status: %w", result.Error)
}
if result.RowsAffected == 0 {
return fmt.Errorf("user not found")
}
return nil
}
func (r *approvalRepository) GetApprovalSummary(ctx context.Context) (*ApprovalSummary, error) {
var summary ApprovalSummary
if err := r.db.WithContext(ctx).
Model(&model.User{}).
Where("registration_status = ? AND registration_progress >= ?", "awaiting_approval", 2).
Count(&summary.TotalPending).Error; err != nil {
return nil, fmt.Errorf("failed to count total pending users: %w", err)
}
if err := r.db.WithContext(ctx).
Model(&model.User{}).
Joins("JOIN roles ON roles.id = users.role_id").
Where("users.registration_status = ? AND users.registration_progress >= ? AND LOWER(roles.role_name) = ?",
"awaiting_approval", 2, "pengelola").
Count(&summary.PengelolaPending).Error; err != nil {
return nil, fmt.Errorf("failed to count pengelola pending: %w", err)
}
if err := r.db.WithContext(ctx).
Model(&model.User{}).
Joins("JOIN roles ON roles.id = users.role_id").
Where("users.registration_status = ? AND users.registration_progress >= ? AND LOWER(roles.role_name) = ?",
"awaiting_approval", 2, "pengepul").
Count(&summary.PengepulPending).Error; err != nil {
return nil, fmt.Errorf("failed to count pengepul pending: %w", err)
}
return &summary, nil
}
func (r *approvalRepository) GetUsersByIDs(ctx context.Context, userIDs []string) ([]model.User, error) {
var users []model.User
if err := r.db.WithContext(ctx).
Preload("Role").
Preload("IdentityCard").
Preload("CompanyProfile").
Where("id IN ?", userIDs).
Find(&users).Error; err != nil {
return nil, fmt.Errorf("failed to get users by IDs: %w", err)
}
return users, nil
}
func (r *approvalRepository) BulkUpdateRegistrationStatus(ctx context.Context, userIDs []string, status string, progress int8) error {
result := r.db.WithContext(ctx).
Model(&model.User{}).
Where("id IN ?", userIDs).
Updates(map[string]interface{}{
"registration_status": status,
"registration_progress": progress,
"updated_at": "NOW()",
})
if result.Error != nil {
return fmt.Errorf("failed to bulk update registration status: %w", result.Error)
}
if result.RowsAffected == 0 {
return fmt.Errorf("no users found to update")
}
return nil
}