213 lines
6.5 KiB
Go
213 lines
6.5 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
|
|
"eslogad-be/internal/entities"
|
|
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type DispositionRouteRepository struct{ db *gorm.DB }
|
|
|
|
func NewDispositionRouteRepository(db *gorm.DB) *DispositionRouteRepository {
|
|
return &DispositionRouteRepository{db: db}
|
|
}
|
|
|
|
func (r *DispositionRouteRepository) Create(ctx context.Context, e *entities.DispositionRoute) error {
|
|
db := DBFromContext(ctx, r.db)
|
|
return db.WithContext(ctx).Create(e).Error
|
|
}
|
|
|
|
// 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{}).
|
|
Where("id = ?", existing.ID).
|
|
Updates(e).Error
|
|
}
|
|
|
|
// 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() {
|
|
if err != nil {
|
|
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{
|
|
FromDepartmentID: fromDeptID,
|
|
ToDepartmentID: toDeptID,
|
|
IsActive: isActive,
|
|
AllowedActions: allowedActions,
|
|
}
|
|
|
|
if existing, exists := existingMap[toDeptID]; exists {
|
|
// Update existing route
|
|
route.ID = existing.ID
|
|
if err = tx.Model(&entities.DispositionRoute{}).
|
|
Where("id = ?", existing.ID).
|
|
Updates(&route).Error; err != nil {
|
|
return created, updated, err
|
|
}
|
|
updated++
|
|
// Remove from map to track which routes to delete
|
|
delete(existingMap, toDeptID)
|
|
} else {
|
|
// Create new route
|
|
if err = tx.Create(&route).Error; err != nil {
|
|
return created, updated, err
|
|
}
|
|
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 {
|
|
if err = tx.Model(&entities.DispositionRoute{}).
|
|
Where("id = ?", oldRoute.ID).
|
|
Update("is_active", false).Error; err != nil {
|
|
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 {
|
|
db := DBFromContext(ctx, r.db)
|
|
return db.WithContext(ctx).Model(&entities.DispositionRoute{}).Where("id = ?", e.ID).Updates(e).Error
|
|
}
|
|
|
|
func (r *DispositionRouteRepository) Get(ctx context.Context, id uuid.UUID) (*entities.DispositionRoute, error) {
|
|
db := DBFromContext(ctx, r.db)
|
|
var e entities.DispositionRoute
|
|
if err := db.WithContext(ctx).
|
|
Preload("FromDepartment").
|
|
Preload("ToDepartment").
|
|
First(&e, "id = ?", id).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &e, nil
|
|
}
|
|
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).
|
|
Preload("FromDepartment").
|
|
Preload("ToDepartment").
|
|
Order("to_department_id").Find(&list).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return list, nil
|
|
}
|
|
|
|
func (r *DispositionRouteRepository) IsEligibleForDisposition(ctx context.Context, fromDept uuid.UUID) (bool, error) {
|
|
db := DBFromContext(ctx, r.db)
|
|
var list []entities.DispositionRoute
|
|
if err := db.WithContext(ctx).Where("from_department_id = ?", fromDept).Find(&list).Error; err != nil {
|
|
return false, err
|
|
}
|
|
return len(list) > 0, nil
|
|
}
|
|
|
|
func (r *DispositionRouteRepository) SetActive(ctx context.Context, id uuid.UUID, isActive bool) error {
|
|
db := DBFromContext(ctx, r.db)
|
|
return db.WithContext(ctx).Model(&entities.DispositionRoute{}).Where("id = ?", id).Update("is_active", isActive).Error
|
|
}
|
|
|
|
// ListAllGrouped returns all disposition routes grouped by from_department_id
|
|
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
|
|
}
|
|
|
|
// ListAllGroupedWithDepartments returns all disposition routes grouped by from_department_id with department details
|
|
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").
|
|
Where("is_active = ?", true).
|
|
Order("from_department_id, to_department_id").
|
|
Find(&routes).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return routes, nil
|
|
}
|
|
|
|
// ListAll returns all disposition routes with department details
|
|
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").
|
|
Where("is_active = ?", true).
|
|
Order("from_department_id, to_department_id").
|
|
Find(&routes).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return routes, nil
|
|
}
|