public async Task <Appointment> GetUpcomingAppointment(Guid userId) { var appointment = await Context.Appointments .Include(x => x.CheckingService) .Include(x => x.Doctor) .ThenInclude(x => x.Specialty) .Include(x => x.Doctor) .ThenInclude(d => d.Location) .Include(x => x.Patient) .ThenInclude(x => x.Location) .Where(x => x.PatientId == userId && x.IsActive && x.Status == (int)AppointmentStatus.Confirmed) .OrderBy(x => x.AppointmentDate) .FirstOrDefaultAsync(); if (appointment == null) { return(null); } var distanceFromPatient = LocationHelper.GetDistance(appointment.Patient.Location.Latitude, appointment.Patient.Location.Longitude, appointment.Doctor.Location.Latitude, appointment.Doctor.Location.Longitude) / 1000; var result = _mapper.Map <Appointment>(appointment); result.Doctor.DistanceFromPatient = distanceFromPatient; return(result); }
public async Task <PagedResult <Doctor> > GetDoctorsAsync(Guid userId, int page, int pageSize, FilterDoctor filter, SortOptions <SortDoctorField> sortOptions) { var user = await Context.Patients.Include(x => x.Location).FirstOrDefaultAsync(x => x.Id == userId) ?? throw new EntityNotFoundException(); var query = Context.Doctors .IncludeMultiple(x => x.Specialty, x => x.Location, x => x.Reviews, x => x.Favorites) .IncludeMultipleIf( filter.AvailableToday.GetValueOrDefault(), x => x.Appointments, x => x.WorkingSchedules, x => x.NoAttendances) .Where(x => x.IsActive) .SearchByFields(filter.SearchTerm, x => x.FirstName, x => x.LastName, x => x.Clinic) .WhereIf(filter.SpecialtyId.HasValue, x => x.SpecialtyId == filter.SpecialtyId) .WhereIf(filter.Gender.HasValue, x => x.Gender == filter.Gender) .WhereIf(filter.YearExperience.HasValue, GetCompareYearExperiencePredicate(filter.FilterYearExperienceSymbol, filter.YearExperience)) .Select(x => new DoctorProjection { Id = x.Id, FirstName = x.FirstName, LastName = x.LastName, Gender = x.Gender, YearExperience = x.YearExperience, Awards = x.Awards, ImageProfile = x.ImageProfile, MedicalSchool = x.MedicalSchool, Clinic = x.Clinic, About = x.About, Location = x.Location, Specialty = x.Specialty, Rating = x.Reviews.Any() ? (((decimal?)x.Reviews.Where(r => r.IsActive).Sum(r => r.Rating) / x.Reviews.Count(r => r.IsActive))) : 0, RatingCount = x.Reviews.Count(r => r.IsActive), DistanceFromPatient = LocationHelper.GetDistance(user.Location.Latitude, user.Location.Longitude, x.Location.Latitude, x.Location.Longitude) / 1000, IsFavorited = x.Favorites.Any(f => f.PatientId == userId && f.IsActive) }); if (filter.AvailableToday.HasValue) { // Implement later } switch (sortOptions?.SortByField) { case SortDoctorField.Price: query = query.OrderByElseDescending(sortOptions.SortOrder == SortOrder.Asc, x => x.Price); break; case SortDoctorField.Distance: query = query.OrderByElseDescending(sortOptions.SortOrder == SortOrder.Asc, x => x.DistanceFromPatient); break; case SortDoctorField.StarRating: query = query.OrderByElseDescending(sortOptions.SortOrder == SortOrder.Asc, x => x.Rating); break; default: break; } return(await query.GetPagedResultAsync(page, pageSize, x => _mapper.Map <Doctor>(x))); }
public async Task <DoctorDetails> GetDoctorAsync(Guid userId, Guid doctorId) { var user = await Context.Patients.Include(x => x.Location).FirstOrDefaultAsync(x => x.Id == userId) ?? throw new EntityNotFoundException(); var doctor = await Context.Doctors .IncludeMultiple(x => x.Specialty, x => x.Reviews, x => x.Location, x => x.Appointments, x => x.Favorites) .Where(x => x.Id == doctorId && x.IsActive) .Select(x => new DoctorDetailsProjection { Id = x.Id, FirstName = x.FirstName, LastName = x.LastName, Gender = x.Gender, YearExperience = x.YearExperience, Awards = x.Awards, ImageProfile = x.ImageProfile, MedicalSchool = x.MedicalSchool, Clinic = x.Clinic, About = x.About, Location = x.Location, Specialty = x.Specialty, Rating = ((decimal?)x.Reviews.Where(r => r.IsActive).Sum(r => r.Rating) / x.Reviews.Count(r => r.IsActive)) ?? 0, RatingCount = x.Reviews.Count(r => r.IsActive), DistanceFromPatient = LocationHelper.GetDistance(user.Location.Latitude, user.Location.Longitude, x.Location.Latitude, x.Location.Longitude) / 1000, NumberOfPatients = x.Appointments.Where(a => a.IsActive && a.Status == (int)AppointmentStatus.Completed).Select(a => a.PatientId).Count(), // Distinct here, IsFavorited = x.Favorites.Any(f => f.PatientId == userId && f.IsActive) }) .FirstOrDefaultAsync(); if (doctor == null) { throw new EntityNotFoundException(typeof(DbDoctor), doctorId); } return(_mapper.Map <DoctorDetails>(doctor)); }
public void GetDistance() { // Values used for comparison comes from lines plotted into Google Maps. Google uses a varying number // decimals depending on the distance, so we loose a bit precision when rounding. But the results of this // unit test still shows that the method works (eg. the test will fail if using the mean radius rather than // the equatorial radius). var samples = new[] { new { From = new EssentialsLocation(55.6946159, 10.0366974), To = new EssentialsLocation(55.6477614, 10.1589203), Expected = "9.28", Decimals = 2 }, new { From = new EssentialsLocation(54.8671242, 7.7124023), To = new EssentialsLocation(56.8159142, 12.2113037), Expected = "355", Decimals = 0 }, new { From = new EssentialsLocation(49.2104204, -6.1083984), To = new EssentialsLocation(59.578851, 22.9833984), Expected = "2184", Decimals = 0 }, new { From = new EssentialsLocation(12.3829283, -71.3671875), To = new EssentialsLocation(71.2443555, 25.4882813), Expected = "8958", Decimals = 0 } }; foreach (var sample in samples) { string format = "{0:0." + ("".PadLeft(sample.Decimals, '0')) + "}"; Assert.AreEqual(sample.Expected, String.Format(CultureInfo.InvariantCulture, format, LocationHelper.GetDistance(sample.From, sample.To) / 1000)); Assert.AreEqual(sample.Expected, String.Format(CultureInfo.InvariantCulture, format, LocationUtils.GetDistance(sample.From, sample.To) / 1000)); } }
public bool IsMatch(User newUser, User existingUser) { var dis = LocationHelper.GetDistance(newUser.Address.Latitude, newUser.Address.Longitude, existingUser.Address.Latitude, existingUser.Address.Longitude); return(dis <= 500); }