Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public async Task<AppointmentDetailDto> Handle(
.AsNoTracking()
.Include(a => a.Doctor)
.ThenInclude(d => d.Specialty)
.Include(b => b.Doctor)
.ThenInclude(d => d.ApplicationUser)
.Include(a => a.Patient)
.ThenInclude(p => p.ApplicationUser)
.Include(a => a.Attachments)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Booking.Application.Doctors.Command.DeleteDoctor
{
[Serializable]
internal class ForbiddenAccessException : Exception
{
public ForbiddenAccessException()
{
}

public ForbiddenAccessException(string? message) : base(message)
{
}

public ForbiddenAccessException(string? message, Exception? innerException) : base(message, innerException)
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ public async Task<Guid> Handle(
CreateDoctorCommand createDoctor,
CancellationToken cancellationToken)
{
var user = new ApplicationUser
{
UserName = createDoctor.Email,
Email = createDoctor.Email,
FirstName = createDoctor.Name,
LastName = createDoctor.Lastname,
PhoneNumber = createDoctor.PhoneNumber,
EmailConfirmed = true,
};
var user = ApplicationUser.CreateDoctor
(
email: createDoctor.Email,
firstName: createDoctor.Name,
lastName: createDoctor.Lastname,
phoneNumber: createDoctor.PhoneNumber
);

(await _userManager.CreateAsync(user, createDoctor.Password))
.EnsureSucceeded("CreateDoctor");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Booking.Application.Common.Exceptions;
using Booking.Application.Common.Interfaces;
using Booking.Domain.Constants;
using Booking.Domain.Entities;
using MediatR;
using Microsoft.EntityFrameworkCore;
Expand All @@ -8,20 +9,30 @@ namespace Booking.Application.Doctors.Command.DeleteDoctor
{
public class DeleteDoctorCommandHandler(
IBookingDbContext context,
IIdentityService identityService)
IIdentityService identityService,
ICurrentUserService userService)
: IRequestHandler<DeleteDoctorCommand>
{
private readonly IBookingDbContext _context = context;
private readonly IIdentityService _identityService = identityService;
private readonly ICurrentUserService _currentUserService = userService;

public async Task Handle(
DeleteDoctorCommand request,
CancellationToken cancellationToken)
{
var currentUser = _currentUserService.UserId;

if (string.IsNullOrEmpty(currentUser))
throw new UnauthorizedAccessException("User is not authenticated.");

if (!await _identityService.IsInRoleAsync(currentUser, Roles.Admin))
throw new ForbiddenAccessException("Only administrators can delete doctors");

var doctor = await _context.Doctors
.Include(d => d.Appointments)
.FirstOrDefaultAsync(d => d.Id == request.DoctorId, cancellationToken)
?? throw new NotFoundException(nameof(Doctor), request.DoctorId);
.Include(d => d.Appointments)
.FirstOrDefaultAsync(d => d.Id == request.DoctorId, cancellationToken)
?? throw new NotFoundException(nameof(Doctor), request.DoctorId);


var hasActiveAppointments = doctor.Appointments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public async Task<Unit> Handle(
var currentUser = await _userManager.FindByIdAsync(currentDoctorId);
var isAdmin = currentUser != null && await _userManager.IsInRoleAsync(currentUser, Roles.Admin);

if (!isOwner && isAdmin)
if (!isOwner && !isAdmin)
throw new UnauthorizedAccessException("You can only edit your own profile.");

doctor.UpdateProfile(
Expand All @@ -45,9 +45,10 @@ public async Task<Unit> Handle(
request.IsActive,
request.ConsultationFee);

doctor.ApplicationUser.FirstName = request.Name;
doctor.ApplicationUser.LastName = request.Lastname;
doctor.ApplicationUser.PhoneNumber = request.PhoneNumber;
doctor.ApplicationUser.UpdatePersonalInfo(
request.Name,
request.Lastname,
request.PhoneNumber);

await _dbContext.SaveChangesAsync(cancellationToken);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,14 @@ public async Task<string> Handle(
RegisterUserCommand request,
CancellationToken cancellationToken)
{
var user = new ApplicationUser
{
FirstName = request.UserName,
LastName = request.UserSurname,
Email = request.UserEmail,
UserName = request.UserEmail,
PhoneNumber = request.PhoneNumber,
Address = request.Address,
EmailConfirmed = true
};
var user = ApplicationUser.CreatePatient
(
firstName: request.UserName,
lastName: request.UserSurname,
email: request.UserEmail,
phoneNumber: request.PhoneNumber ?? string.Empty,
adress: request.Address ?? string.Empty
);

var createResult = await _userManager.CreateAsync(user, request.UserPassword);

Expand Down
75 changes: 69 additions & 6 deletions src/Booking/Booking.Domain/Entities/ApplicationUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,75 @@
{
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public string? PhotoUrl { get; set; }
public string? Address { get; set; }
public string FirstName { get; private set; }
public string LastName { get; private set; }
public string? PhotoUrl { get; private set; }
public string? Address { get; private set; }

public virtual Patient? PatientProfile { get; set; }
public virtual Doctor? DoctorProfile { get; set; }
public virtual Patient? PatientProfile { get; private set; }
public virtual Doctor? DoctorProfile { get; private set; }

private ApplicationUser() { }

Check warning on line 15 in src/Booking/Booking.Domain/Entities/ApplicationUser.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'LastName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 15 in src/Booking/Booking.Domain/Entities/ApplicationUser.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'FirstName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 15 in src/Booking/Booking.Domain/Entities/ApplicationUser.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'LastName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 15 in src/Booking/Booking.Domain/Entities/ApplicationUser.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'FirstName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 15 in src/Booking/Booking.Domain/Entities/ApplicationUser.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'LastName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 15 in src/Booking/Booking.Domain/Entities/ApplicationUser.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'FirstName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 15 in src/Booking/Booking.Domain/Entities/ApplicationUser.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'LastName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 15 in src/Booking/Booking.Domain/Entities/ApplicationUser.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'FirstName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

public ApplicationUser(
string firstName,
string lastName,
string address)
{
FirstName = firstName;
LastName = lastName;
Address = address;
}

public static ApplicationUser CreateDoctor(
string email,
string firstName,
string lastName,
string phoneNumber)
{
return new ApplicationUser
{
UserName = email,
Email = email,
FirstName = firstName,
LastName = lastName,
PhoneNumber = phoneNumber,
EmailConfirmed = true
};
}

public void UpdatePersonalInfo(
string name,
string lastname,
string? phoneNumber)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentException("Name cannot be empty.");
if (string.IsNullOrEmpty(lastname))
throw new ArgumentException("Last name cannot be empty.");

FirstName = name;
LastName = lastname;
PhoneNumber = phoneNumber;
}

public static ApplicationUser CreatePatient(
string firstName,
string lastName,
string email,
string phoneNumber,
string adress)
{
return new ApplicationUser
{
UserName = email,
Email = email,
FirstName = firstName,
LastName = lastName,
PhoneNumber = phoneNumber,
Address = adress,
EmailConfirmed = true
};
}
}
}
Loading