Update department etc
This commit is contained in:
@@ -23,20 +23,20 @@ func (r *DispositionRouteRepository) Create(ctx context.Context, e *entities.Dis
|
||||
// Upsert creates or updates a disposition route based on from_department_id and to_department_id
|
||||
func (r *DispositionRouteRepository) Upsert(ctx context.Context, e *entities.DispositionRoute) error {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
|
||||
|
||||
// Check if route exists
|
||||
var existing entities.DispositionRoute
|
||||
err := db.WithContext(ctx).
|
||||
Where("from_department_id = ? AND to_department_id = ?", e.FromDepartmentID, e.ToDepartmentID).
|
||||
First(&existing).Error
|
||||
|
||||
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
// Create new route
|
||||
return db.WithContext(ctx).Create(e).Error
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// Update existing route
|
||||
e.ID = existing.ID
|
||||
return db.WithContext(ctx).Model(&entities.DispositionRoute{}).
|
||||
@@ -47,7 +47,7 @@ func (r *DispositionRouteRepository) Upsert(ctx context.Context, e *entities.Dis
|
||||
// BulkUpsert performs bulk create or update for multiple routes
|
||||
func (r *DispositionRouteRepository) BulkUpsert(ctx context.Context, fromDeptID uuid.UUID, toDeptIDs []uuid.UUID, isActive bool, allowedActions entities.JSONB) (created int, updated int, err error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
|
||||
|
||||
// Start transaction
|
||||
tx := db.WithContext(ctx).Begin()
|
||||
defer func() {
|
||||
@@ -55,19 +55,19 @@ func (r *DispositionRouteRepository) BulkUpsert(ctx context.Context, fromDeptID
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
// Get existing routes for this from_department_id
|
||||
var existingRoutes []entities.DispositionRoute
|
||||
if err = tx.Where("from_department_id = ?", fromDeptID).Find(&existingRoutes).Error; err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
|
||||
// Create map of existing routes
|
||||
existingMap := make(map[uuid.UUID]entities.DispositionRoute)
|
||||
for _, route := range existingRoutes {
|
||||
existingMap[route.ToDepartmentID] = route
|
||||
}
|
||||
|
||||
|
||||
// Process each to_department_id
|
||||
for _, toDeptID := range toDeptIDs {
|
||||
route := entities.DispositionRoute{
|
||||
@@ -76,7 +76,7 @@ func (r *DispositionRouteRepository) BulkUpsert(ctx context.Context, fromDeptID
|
||||
IsActive: isActive,
|
||||
AllowedActions: allowedActions,
|
||||
}
|
||||
|
||||
|
||||
if existing, exists := existingMap[toDeptID]; exists {
|
||||
// Update existing route
|
||||
route.ID = existing.ID
|
||||
@@ -96,7 +96,7 @@ func (r *DispositionRouteRepository) BulkUpsert(ctx context.Context, fromDeptID
|
||||
created++
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Optionally deactivate routes that are no longer in the list
|
||||
// (routes that exist in DB but not in the new list)
|
||||
for _, oldRoute := range existingMap {
|
||||
@@ -106,12 +106,12 @@ func (r *DispositionRouteRepository) BulkUpsert(ctx context.Context, fromDeptID
|
||||
return created, updated, err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Commit transaction
|
||||
if err = tx.Commit().Error; err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
|
||||
return created, updated, nil
|
||||
}
|
||||
func (r *DispositionRouteRepository) Update(ctx context.Context, e *entities.DispositionRoute) error {
|
||||
@@ -133,7 +133,7 @@ func (r *DispositionRouteRepository) Get(ctx context.Context, id uuid.UUID) (*en
|
||||
func (r *DispositionRouteRepository) ListByFromDept(ctx context.Context, fromDept uuid.UUID) ([]entities.DispositionRoute, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
var list []entities.DispositionRoute
|
||||
if err := db.WithContext(ctx).Where("from_department_id = ?", fromDept).
|
||||
if err := db.WithContext(ctx).Where("from_department_id = ? and is_active=true", fromDept).
|
||||
Preload("FromDepartment").
|
||||
Preload("ToDepartment").
|
||||
Order("to_department_id").Find(&list).Error; err != nil {
|
||||
@@ -160,20 +160,20 @@ func (r *DispositionRouteRepository) SetActive(ctx context.Context, id uuid.UUID
|
||||
func (r *DispositionRouteRepository) ListAllGrouped(ctx context.Context) (map[uuid.UUID][]uuid.UUID, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
var routes []entities.DispositionRoute
|
||||
|
||||
|
||||
if err := db.WithContext(ctx).
|
||||
Where("is_active = ?", true).
|
||||
Order("from_department_id, to_department_id").
|
||||
Find(&routes).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
// Group by from_department_id
|
||||
grouped := make(map[uuid.UUID][]uuid.UUID)
|
||||
for _, route := range routes {
|
||||
grouped[route.FromDepartmentID] = append(grouped[route.FromDepartmentID], route.ToDepartmentID)
|
||||
}
|
||||
|
||||
|
||||
return grouped, nil
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ func (r *DispositionRouteRepository) ListAllGrouped(ctx context.Context) (map[uu
|
||||
func (r *DispositionRouteRepository) ListAllGroupedWithDepartments(ctx context.Context) ([]entities.DispositionRoute, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
var routes []entities.DispositionRoute
|
||||
|
||||
|
||||
if err := db.WithContext(ctx).
|
||||
Preload("FromDepartment").
|
||||
Preload("ToDepartment").
|
||||
@@ -190,7 +190,7 @@ func (r *DispositionRouteRepository) ListAllGroupedWithDepartments(ctx context.C
|
||||
Find(&routes).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ func (r *DispositionRouteRepository) ListAllGroupedWithDepartments(ctx context.C
|
||||
func (r *DispositionRouteRepository) ListAll(ctx context.Context) ([]entities.DispositionRoute, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
var routes []entities.DispositionRoute
|
||||
|
||||
|
||||
if err := db.WithContext(ctx).
|
||||
Preload("FromDepartment").
|
||||
Preload("ToDepartment").
|
||||
@@ -207,6 +207,6 @@ func (r *DispositionRouteRepository) ListAll(ctx context.Context) ([]entities.Di
|
||||
Find(&routes).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
@@ -225,6 +225,45 @@ func (r *DepartmentRepository) List(ctx context.Context, search string, limit, o
|
||||
return list, total, nil
|
||||
}
|
||||
|
||||
func (r *DepartmentRepository) ListWithParentFilter(ctx context.Context, search string, limit, offset int, parentPath string, excludedPaths []string) ([]entities.Department, int64, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
|
||||
query := db.WithContext(ctx).Model(&entities.Department{})
|
||||
|
||||
// Filter by parent path if provided - include the parent itself and all descendants
|
||||
if parentPath != "" {
|
||||
query = query.Where("path = ? OR path <@ ?", parentPath, parentPath)
|
||||
}
|
||||
|
||||
// Exclude specific paths
|
||||
for _, excludedPath := range excludedPaths {
|
||||
query = query.Where("NOT (path ~ ?)", excludedPath)
|
||||
}
|
||||
|
||||
// Add search filter if provided
|
||||
if search != "" {
|
||||
query = query.Where("name ILIKE ? OR code ILIKE ?", "%"+search+"%", "%"+search+"%")
|
||||
}
|
||||
|
||||
// Get total count
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// Get paginated results
|
||||
var list []entities.Department
|
||||
if err := query.
|
||||
Order("name ASC").
|
||||
Limit(limit).
|
||||
Offset(offset).
|
||||
Find(&list).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return list, total, nil
|
||||
}
|
||||
|
||||
func (r *DepartmentRepository) GetByID(ctx context.Context, id uuid.UUID) (*entities.Department, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
var e entities.Department
|
||||
@@ -233,3 +272,98 @@ func (r *DepartmentRepository) GetByID(ctx context.Context, id uuid.UUID) (*enti
|
||||
}
|
||||
return &e, nil
|
||||
}
|
||||
|
||||
func (r *DepartmentRepository) Create(ctx context.Context, department *entities.Department) error {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
return db.WithContext(ctx).Create(department).Error
|
||||
}
|
||||
|
||||
func (r *DepartmentRepository) Update(ctx context.Context, department *entities.Department) error {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
return db.WithContext(ctx).Save(department).Error
|
||||
}
|
||||
|
||||
func (r *DepartmentRepository) Delete(ctx context.Context, id uuid.UUID) error {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
return db.WithContext(ctx).Delete(&entities.Department{}, "id = ?", id).Error
|
||||
}
|
||||
|
||||
func (r *DepartmentRepository) GetByPath(ctx context.Context, path string) (*entities.Department, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
var department entities.Department
|
||||
if err := db.WithContext(ctx).Where("path = ?", path).First(&department).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &department, nil
|
||||
}
|
||||
|
||||
func (r *DepartmentRepository) GetAll(ctx context.Context) ([]entities.Department, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
var departments []entities.Department
|
||||
if err := db.WithContext(ctx).Order("path ASC").Find(&departments).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return departments, nil
|
||||
}
|
||||
|
||||
func (r *DepartmentRepository) GetAllWithParentFilter(ctx context.Context, parentPath string, excludedPaths []string) ([]entities.Department, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
var departments []entities.Department
|
||||
|
||||
query := db.WithContext(ctx)
|
||||
|
||||
// Filter by parent path if provided - include the parent itself and all descendants
|
||||
if parentPath != "" {
|
||||
query = query.Where("path = ? OR path <@ ?", parentPath, parentPath)
|
||||
}
|
||||
|
||||
// Exclude specific paths
|
||||
for _, excludedPath := range excludedPaths {
|
||||
query = query.Where("NOT (path ~ ?)", excludedPath)
|
||||
}
|
||||
|
||||
if err := query.Order("path ASC").Find(&departments).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return departments, nil
|
||||
}
|
||||
|
||||
func (r *DepartmentRepository) GetByPathPrefix(ctx context.Context, pathPrefix string) ([]entities.Department, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
var departments []entities.Department
|
||||
// Using ltree operators for hierarchical queries
|
||||
query := db.WithContext(ctx).Order("path ASC")
|
||||
if pathPrefix != "" {
|
||||
// Get all descendants of a path
|
||||
query = query.Where("path <@ ?", pathPrefix)
|
||||
}
|
||||
if err := query.Find(&departments).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return departments, nil
|
||||
}
|
||||
|
||||
func (r *DepartmentRepository) GetChildren(ctx context.Context, parentPath string) ([]entities.Department, error) {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
var departments []entities.Department
|
||||
// Get direct children and all descendants
|
||||
if err := db.WithContext(ctx).
|
||||
Where("path <@ ? AND path != ?", parentPath, parentPath).
|
||||
Order("path ASC").
|
||||
Find(&departments).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return departments, nil
|
||||
}
|
||||
|
||||
func (r *DepartmentRepository) UpdateChildrenPaths(ctx context.Context, oldPath, newPath string) error {
|
||||
db := DBFromContext(ctx, r.db)
|
||||
// Use raw SQL for ltree path update
|
||||
// This will update all children paths by replacing the old prefix with the new one
|
||||
query := `
|
||||
UPDATE departments
|
||||
SET path = ? || subpath(path, nlevel(?))
|
||||
WHERE path <@ ? AND path != ?
|
||||
`
|
||||
return db.WithContext(ctx).Exec(query, newPath, oldPath, oldPath, oldPath).Error
|
||||
}
|
||||
|
||||
@@ -194,26 +194,86 @@ func (r *UserRepositoryImpl) ListWithFilters(ctx context.Context, search *string
|
||||
var users []*entities.User
|
||||
var total int64
|
||||
|
||||
q := r.b.WithContext(ctx).Table("users").Model(&entities.User{})
|
||||
// Build base query - use Model directly without Table for proper field mapping
|
||||
baseQuery := r.b.WithContext(ctx).Model(&entities.User{})
|
||||
|
||||
if search != nil && *search != "" {
|
||||
like := "%" + *search + "%"
|
||||
q = q.Where("users.name ILIKE ?", like)
|
||||
baseQuery = baseQuery.Where("name ILIKE ? OR email ILIKE ?", like, like)
|
||||
}
|
||||
|
||||
if isActive != nil {
|
||||
q = q.Where("users.is_active = ?", *isActive)
|
||||
baseQuery = baseQuery.Where("is_active = ?", *isActive)
|
||||
}
|
||||
|
||||
// For counting with role filter, we need to use a subquery or join
|
||||
countQuery := baseQuery
|
||||
if roleCode != nil && *roleCode != "" {
|
||||
q = q.Joins("JOIN user_role ur ON ur.user_id = users.id AND ur.removed_at IS NULL").
|
||||
countQuery = countQuery.
|
||||
Joins("JOIN user_role ur ON ur.user_id = users.id AND ur.removed_at IS NULL").
|
||||
Joins("JOIN roles r ON r.id = ur.role_id").
|
||||
Where("r.code = ?", *roleCode)
|
||||
}
|
||||
|
||||
if err := q.Distinct("users.id").Count(&total).Error; err != nil {
|
||||
// Get total count
|
||||
if err := countQuery.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if err := q.Select("users.*").Distinct("users.id").Limit(limit).Offset(offset).Preload("Profile").Preload("Departments").Find(&users).Error; err != nil {
|
||||
// Build query for fetching data
|
||||
dataQuery := r.b.WithContext(ctx).Model(&entities.User{})
|
||||
|
||||
if search != nil && *search != "" {
|
||||
like := "%" + *search + "%"
|
||||
dataQuery = dataQuery.Where("name ILIKE ? OR email ILIKE ?", like, like)
|
||||
}
|
||||
|
||||
if isActive != nil {
|
||||
dataQuery = dataQuery.Where("is_active = ?", *isActive)
|
||||
}
|
||||
|
||||
if roleCode != nil && *roleCode != "" {
|
||||
dataQuery = dataQuery.
|
||||
Joins("JOIN user_role ur ON ur.user_id = users.id AND ur.removed_at IS NULL").
|
||||
Joins("JOIN roles r ON r.id = ur.role_id").
|
||||
Where("r.code = ?", *roleCode)
|
||||
}
|
||||
|
||||
// Fetch users with preloads
|
||||
if err := dataQuery.
|
||||
Limit(limit).
|
||||
Offset(offset).
|
||||
Preload("Profile").
|
||||
Preload("Departments").
|
||||
Find(&users).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return users, total, nil
|
||||
}
|
||||
|
||||
func (r *UserRepositoryImpl) GetByIDWithDepartments(ctx context.Context, id uuid.UUID) (*entities.User, error) {
|
||||
var user entities.User
|
||||
err := r.b.WithContext(ctx).
|
||||
Preload("Profile").
|
||||
Preload("Departments").
|
||||
First(&user, "id = ?", id).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (r *UserRepositoryImpl) UpdateDepartments(ctx context.Context, userID uuid.UUID, departments []entities.Department) error {
|
||||
// First, clear existing associations
|
||||
if err := r.b.WithContext(ctx).Model(&entities.User{ID: userID}).Association("Departments").Clear(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Then add new associations
|
||||
if len(departments) > 0 {
|
||||
return r.b.WithContext(ctx).Model(&entities.User{ID: userID}).Association("Departments").Append(&departments)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user