155 lines
6.7 KiB
C#
155 lines
6.7 KiB
C#
using Microsoft.EntityFrameworkCore;
|
||
using Nashel.Modules.Identity.Domain.Aggregates;
|
||
using Nashel.Modules.Identity.Domain.Entities;
|
||
using Nashel.Modules.Identity.Domain.Repositories;
|
||
using Nashel.Modules.Identity.Infrastructure.Persistence;
|
||
|
||
namespace Nashel.Modules.Identity.Infrastructure.Repositories;
|
||
|
||
public class AccountRepository : IAccountRepository
|
||
{
|
||
private readonly IdentityDbContext _context;
|
||
|
||
public AccountRepository(IdentityDbContext context)
|
||
{
|
||
_context = context;
|
||
}
|
||
|
||
public async Task AddAsync(Account account, CancellationToken cancellationToken)
|
||
{
|
||
// Явно добавляем профиль, чтобы EF Core сохранил его в таблицу UserProfiles
|
||
if (account.Profile != null)
|
||
{
|
||
await _context.UserProfiles.AddAsync(account.Profile, cancellationToken);
|
||
|
||
// Добавляем WorkSchedule если есть
|
||
if (account.Profile.WorkSchedule != null)
|
||
{
|
||
await _context.WorkSchedules.AddAsync(account.Profile.WorkSchedule, cancellationToken);
|
||
}
|
||
}
|
||
await _context.Accounts.AddAsync(account, cancellationToken);
|
||
await _context.SaveChangesAsync(cancellationToken);
|
||
}
|
||
|
||
public async Task<Account?> GetByIdAsync(Guid id, CancellationToken cancellationToken)
|
||
{
|
||
return await _context.Accounts
|
||
.Include(a => a.Profile)
|
||
.ThenInclude(p => p.Competencies)
|
||
.Include(a => a.Profile)
|
||
.ThenInclude(p => p.WorkSchedule)
|
||
.FirstOrDefaultAsync(a => a.Id == id, cancellationToken);
|
||
}
|
||
|
||
public async Task<List<Account>> GetByIdsAsync(IEnumerable<Guid> ids, CancellationToken cancellationToken)
|
||
{
|
||
return await _context.Accounts
|
||
.Include(a => a.Profile)
|
||
.Where(a => ids.Contains(a.Id))
|
||
.ToListAsync(cancellationToken);
|
||
}
|
||
|
||
public async Task<Account?> GetByPhoneAsync(string phone, CancellationToken cancellationToken)
|
||
{
|
||
return await _context.Accounts
|
||
.Include(a => a.Profile)
|
||
.FirstOrDefaultAsync(a => a.Phone == phone, cancellationToken);
|
||
}
|
||
|
||
public async Task<Account?> GetByPhoneIncludingDeletedAsync(string phone, CancellationToken cancellationToken)
|
||
{
|
||
return await _context.Accounts
|
||
.IgnoreQueryFilters()
|
||
.Include(a => a.Profile)
|
||
.FirstOrDefaultAsync(a => a.Phone == phone, cancellationToken);
|
||
}
|
||
|
||
public async Task UpdateAsync(Account account, CancellationToken cancellationToken)
|
||
{
|
||
Console.WriteLine($"[AccountRepository.UpdateAsync] Starting update for account: {account.Id}");
|
||
|
||
// Явно обновляем профиль, чтобы EF Core сохранил изменения в таблицу UserProfiles
|
||
if (account.Profile != null)
|
||
{
|
||
Console.WriteLine($"[AccountRepository.UpdateAsync] Profile found: {account.Profile.Id}");
|
||
|
||
// Загружаем текущий профиль с компетенциями
|
||
var existingProfile = await _context.UserProfiles
|
||
.Include(p => p.Competencies)
|
||
.Include(p => p.WorkSchedule)
|
||
.FirstOrDefaultAsync(p => p.Id == account.Profile.Id, cancellationToken);
|
||
|
||
if (existingProfile != null)
|
||
{
|
||
Console.WriteLine($"[AccountRepository.UpdateAsync] Existing profile loaded");
|
||
|
||
// Обновляем свойства профиля
|
||
existingProfile.Update(
|
||
account.Profile.FirstName,
|
||
account.Profile.LastName,
|
||
account.Profile.Patronymic,
|
||
account.Profile.CompanyName,
|
||
account.Profile.Inn,
|
||
account.Profile.Description,
|
||
account.Profile.Location,
|
||
account.Profile.CurrentLocation
|
||
);
|
||
|
||
// Обновляем компетенции через доменный метод
|
||
// Поскольку компетенции уже сохранены через CompetencyRepository,
|
||
// просто загружаем их из БД по Id для правильной работы EF Core
|
||
var competencies = new List<Competency>();
|
||
if (account.Profile.Competencies != null && account.Profile.Competencies.Any())
|
||
{
|
||
var competencyIds = account.Profile.Competencies
|
||
.Select(c => c.Id)
|
||
.Distinct()
|
||
.ToList();
|
||
|
||
Console.WriteLine($"[AccountRepository.UpdateAsync] Loading {competencyIds.Count} competencies from DB");
|
||
competencies = await _context.Competencies
|
||
.Where(c => competencyIds.Contains(c.Id))
|
||
.ToListAsync(cancellationToken);
|
||
}
|
||
existingProfile.UpdateCompetencies(competencies);
|
||
|
||
// Обновляем WorkSchedule
|
||
if (account.Profile.WorkSchedule != null)
|
||
{
|
||
if (existingProfile.WorkSchedule != null)
|
||
{
|
||
// Обновляем существующий WorkSchedule
|
||
existingProfile.WorkSchedule.Update(
|
||
account.Profile.WorkSchedule.IsAlwaysReady,
|
||
account.Profile.WorkSchedule.WorkingDays
|
||
);
|
||
}
|
||
else
|
||
{
|
||
// Создаём новый WorkSchedule
|
||
var newSchedule = WorkSchedule.Create(
|
||
account.Profile.WorkSchedule.IsAlwaysReady,
|
||
account.Profile.WorkSchedule.WorkingDays
|
||
);
|
||
// EF Core сам установит правильную связь через Id профиля
|
||
existingProfile.SetWorkSchedule(newSchedule);
|
||
_context.WorkSchedules.Add(newSchedule);
|
||
}
|
||
}
|
||
|
||
_context.UserProfiles.Update(existingProfile);
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine($"[AccountRepository.UpdateAsync] Existing profile not found, using account profile");
|
||
_context.UserProfiles.Update(account.Profile);
|
||
}
|
||
}
|
||
_context.Accounts.Update(account);
|
||
Console.WriteLine($"[AccountRepository.UpdateAsync] Saving changes to database");
|
||
await _context.SaveChangesAsync(cancellationToken);
|
||
Console.WriteLine($"[AccountRepository.UpdateAsync] Successfully completed");
|
||
}
|
||
}
|