Files
Core_Be/Repos/StaffRepository.cs
T
Dhananjaya99 bffc9b1686 first commit
2026-09-28 11:44:26 +05:30

206 lines
6.9 KiB
C#

using Fitness_core_BE.Interfaces;
using Fitness_core_BE.Models;
using Microsoft.EntityFrameworkCore;
namespace Fitness_core_BE.Repos
{
public class StaffRepository : IStaffRepository
{
private readonly TenantDbContext _context;
private readonly CentralDbContext _central;
public StaffRepository(TenantDbContext context, CentralDbContext central)
{
_context = context;
_central = central;
}
// Staff.User/Staff.Client are central-bucket entities (not a real relationship once
// physically split) -- these load the central User rows separately and attach them
// in memory onto the already-fetched Staff objects, so callers reading staff.User.*
// still see the right data without needing to change.
private async Task AttachUsersAsync(IEnumerable<Staff> staffList)
{
var userIds = staffList.Select(s => s.FKUserId).Distinct().ToList();
if (userIds.Count == 0) return;
var users = await _central.Users
.AsNoTracking()
.Where(u => userIds.Contains(u.UserId))
.ToDictionaryAsync(u => u.UserId);
foreach (var staff in staffList)
{
if (users.TryGetValue(staff.FKUserId, out var user))
staff.User = user;
}
}
public async Task<List<Staff>> GetAllStaff(bool includeInactive = false)
{
var query = _context.Staff
.Include(s => s.GymRole)
.AsQueryable();
if (!includeInactive)
{
query = query.Where(s => s.IsActive);
}
var staffList = await query.ToListAsync();
await AttachUsersAsync(staffList);
return staffList.OrderBy(s => s.User?.UserName).ToList();
}
public async Task<Staff?> GetStaffById(Guid staffId)
{
var staff = await _context.Staff
.Include(s => s.GymRole)
.FirstOrDefaultAsync(s => s.StaffId == staffId);
if (staff != null)
await AttachUsersAsync(new[] { staff });
return staff;
}
public async Task<List<Staff>> GetStaffByClientId(Guid clientId, bool includeInactive = false)
{
var query = _context.Staff
.Include(s => s.GymRole)
.Where(s => s.FKClientId == clientId);
if (!includeInactive)
{
query = query.Where(s => s.IsActive);
}
var staffList = await query.ToListAsync();
await AttachUsersAsync(staffList);
return staffList.OrderBy(s => s.User?.UserName).ToList();
}
public async Task<Staff> CreateStaff(Staff staff, User user)
{
// Create User first (central)
user.UserId = Guid.NewGuid();
user.CreateDate = DateTime.UtcNow;
user.IsActive = true;
_central.Users.Add(user);
// Create Staff (tenant)
staff.StaffId = Guid.NewGuid();
staff.FKUserId = user.UserId;
staff.CreatedAt = DateTime.UtcNow;
staff.HireDate = staff.HireDate == default ? DateTime.UtcNow : staff.HireDate;
staff.IsActive = true;
// Verify Client exists (central)
var clientExists = await _central.Client.AnyAsync(c => c.ClientId == staff.FKClientId);
if (!clientExists)
{
throw new Exception("Client not found");
}
_context.Staff.Add(staff);
return staff;
}
public async Task<Staff> UpdateStaff(Staff staff)
{
var existingStaff = await _context.Staff
.FirstOrDefaultAsync(s => s.StaffId == staff.StaffId);
if (existingStaff == null)
{
throw new Exception("Staff not found");
}
// Update User fields if provided -- User lives in the central DB.
if (staff.User != null && (!string.IsNullOrEmpty(staff.User.UserName)
|| !string.IsNullOrEmpty(staff.User.Email)
|| !string.IsNullOrEmpty(staff.User.PhoneNumber)))
{
var centralUser = await _central.Users.FirstOrDefaultAsync(u => u.UserId == existingStaff.FKUserId);
if (centralUser != null)
{
if (!string.IsNullOrEmpty(staff.User.UserName))
centralUser.UserName = staff.User.UserName;
if (!string.IsNullOrEmpty(staff.User.Email))
centralUser.Email = staff.User.Email;
if (!string.IsNullOrEmpty(staff.User.PhoneNumber))
centralUser.PhoneNumber = staff.User.PhoneNumber;
existingStaff.User = centralUser;
}
}
// Update Staff fields if provided
if (!string.IsNullOrEmpty(staff.StaffPosition))
{
existingStaff.StaffPosition = staff.StaffPosition;
}
if (!string.IsNullOrEmpty(staff.Department))
{
existingStaff.Department = staff.Department;
}
// Update IsActive explicitly
existingStaff.IsActive = staff.IsActive;
return existingStaff;
}
public async Task<bool> DeleteStaff(Guid staffId, bool softDelete = true)
{
var staff = await _context.Staff.FindAsync(staffId);
if (staff == null)
{
return false;
}
if (softDelete)
{
// Soft delete: just mark as inactive
staff.IsActive = false;
}
else
{
// Hard delete: remove from database
_context.Staff.Remove(staff);
}
return true;
}
public async Task<StaffPayRate?> GetActivePayRateAsync(Guid staffId)
{
return await _context.StaffPayRates
.Where(r => r.FKStaffId == staffId && r.IsActive)
.OrderByDescending(r => r.EffectiveFrom)
.FirstOrDefaultAsync();
}
public async Task<StaffPayRate> AddPayRateAsync(StaffPayRate rate)
{
await _context.StaffPayRates.AddAsync(rate);
return rate;
}
public async Task<List<StaffPayment>> GetPaymentsAsync(Guid staffId)
{
return await _context.StaffPayments
.AsNoTracking()
.Where(p => p.FKStaffId == staffId)
.OrderByDescending(p => p.PaidAt)
.ToListAsync();
}
public async Task<StaffPayment> AddPaymentAsync(StaffPayment payment)
{
_context.StaffPayments.Add(payment);
return payment;
}
}
}