first commit
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user