public async Task <BookingAppointmentResult> BookAppointmentAsync( ServiceSupply serviceSupply, PatientModel patinetModel, string Date, string StartTime, string EndTime, bool _existUser, PaymentStatus paymentStatus, ShiftCenterService polyclinicHealthService, ReservationChannel channel, Lang requestLang, int?offerId = null) { var resultMessage = Messages.ErrorOccuredWhileFinalBookTurn; try { if (serviceSupply == null) { throw new ArgumentNullException(nameof(serviceSupply)); } if (string.IsNullOrEmpty(Date) || string.IsNullOrEmpty(StartTime) || string.IsNullOrEmpty(EndTime)) { throw new ArgumentNullException("Date"); } var tmpStatus = paymentStatus == PaymentStatus.NotPayed ? AppointmentStatus.Unknown : AppointmentStatus.Pending; var startDateTime = DateTime.Parse(Date + " " + StartTime); var endDateTime = DateTime.Parse(Date + " " + EndTime); var date = DateTime.Parse(Date).Date; long appointmentId = -1; string trackingCode = string.Empty; var strategy = _dbContext.Database.CreateExecutionStrategy(); await strategy.ExecuteAsync(async() => { using (var transaction = _dbContext.Database.BeginTransaction()) { try { if (offerId != null) { var offer = await _dbContext.Offers.FindAsync(offerId.Value); if (offer == null) { throw new AwroNoreException("Offer Not Found"); } if (offer.RemainedCount <= 0) { throw new AwroNoreException("All Offer Appointments Are Reserved"); } offer.RemainedCount -= 1; _dbContext.Entry(offer).State = EntityState.Modified; await _dbContext.SaveChangesAsync(); } #region book appointment for new user if (!_existUser) { var patientUser = new Person { NamePrefix = patinetModel.NamePrefix, FirstName = patinetModel.FirstName, SecondName = patinetModel.SecondName, ThirdName = patinetModel.ThirdName, Age = patinetModel.Age, Gender = patinetModel.Gender, Mobile = patinetModel.Mobile, ZipCode = patinetModel.ZipCode, Address = patinetModel.Address, Description = patinetModel.Description, CreatedAt = DateTime.Now, IsApproved = true, IsDeleted = false, CreatorRole = Shared.Enums.LoginAs.UNKNOWN, CreationPlaceId = null }; _dbContext.Persons.Add(patientUser); _dbContext.SaveChanges(); // TODO: // var createUser = userManager.Create(patientUser, patinetModel.Password); //if (createUser.Succeeded) //{ // var assignPatientRole = userManager.AddToRole(patientUser.Id, UsersRoleName.Patient.ToString()); // if (!assignPatientRole.Succeeded) // { // throw new Exception(Messages.ErrorOccuredWhileAssignRole); // } //} _dbContext.PatientPersonInfo.Add(new PatientPersonInfo { PersonId = patientUser.Id, CreatedAt = DateTime.Now }); #region Set Patient Insurance int?_patientInsuranceId = null; if (patinetModel.InsuranceId != 0 && patinetModel.InsuranceNumber != null) { var _patientInsurance = new PatientInsurance { UserPatientId = patientUser.Id, ServiceSupplyInsuranceId = patinetModel.InsuranceId, InsuranceNumber = patinetModel.InsuranceNumber, CreatedAt = DateTime.Now }; _dbContext.PatientInsurances.Add(_patientInsurance); _dbContext.SaveChanges(); _patientInsuranceId = _patientInsurance.Id; } #endregion var finalBookabeTimePeriods = _doctorServiceManager.CalculateFinalBookableTimePeriods(serviceSupply, startDateTime, polyclinicHealthService); if (finalBookabeTimePeriods == null || finalBookabeTimePeriods.Count() <= 0) { throw new Exception(Messages.ValidEmptyTimePeriodNotFound); } var ipaTimePeriod = finalBookabeTimePeriods.FirstOrDefault(f => f.StartDateTime == startDateTime && f.EndDateTime == endDateTime && f.Type == TimePeriodType.InProgressAppointment); if (ipaTimePeriod == null) { throw new Exception(Messages.ValidEmptyTimePeriodNotFound); } trackingCode = await _appointmentService.GenerateUniqueTrackingNumberAsync(); var appointment = new Appointment { UniqueTrackingCode = trackingCode, Book_DateTime = DateTime.Now, Start_DateTime = startDateTime, End_DateTime = endDateTime, Description = " ", Status = tmpStatus, ServiceSupplyId = serviceSupply.Id, PersonId = patientUser.Id, PatientInsuranceId = _patientInsuranceId, IsAnnounced = false, Paymentstatus = paymentStatus, IsDeleted = false, ShiftCenterServiceId = polyclinicHealthService.Id, ReservationChannel = channel, CreatedAt = DateTime.Now, OfferId = offerId, RequestLang = requestLang }; _dbContext.Appointments.Add(appointment); _dbContext.SaveChanges(); #region Send SMS notification if (channel != ReservationChannel.Kiosk) { try { var doctor_name = serviceSupply.Person.FullName; var persian_dayOfWeek = Utils.ConvertDayOfWeek(startDateTime.DayOfWeek.ToString()); var day_number = startDateTime.ToShortDateString().Split('/')[2]; var persian_month = Utils.GetMonthName(startDateTime); var year_number = startDateTime.ToShortDateString().Split('/')[0]; var time = startDateTime.ToShortTimeString(); var smsBody = $"{Messages.YourAppointmentForDoctor} { doctor_name} ، { persian_dayOfWeek} { day_number} { persian_month} {year_number} ،{Global.Hour}: {time}"; if (channel == ReservationChannel.ClinicManagerSection) { smsBody = smsBody = "Turn for doctor " + doctor_name + ", " + persian_dayOfWeek + " " + day_number + " " + persian_month + " " + year_number; } string[] recepient = { $"964{patinetModel.Mobile}" }; if (serviceSupply.ShiftCenter.IsIndependent) { if (Lng == Lang.KU) { if (serviceSupply.ShiftCenter.FinalBookSMSMessage_Ku != null) { smsBody = serviceSupply.ShiftCenter.FinalBookSMSMessage_Ku; } } else if (Lng == Lang.AR) { if (serviceSupply.ShiftCenter.FinalBookSMSMessage_Ar != null) { smsBody = serviceSupply.ShiftCenter.FinalBookSMSMessage_Ar; } } } else if (serviceSupply.ShiftCenter.Clinic != null && serviceSupply.ShiftCenter.Clinic.IsIndependent) { if (Lng == Lang.KU) { if (serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ku != null) { smsBody = serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ku; } } else if (Lng == Lang.AR) { if (serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ar != null) { smsBody = serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ar; } } } else if (serviceSupply.ShiftCenter.Clinic != null && serviceSupply.ShiftCenter.Clinic.Hospital != null) { if (Lng == Lang.KU) { if (serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ku != null) { smsBody = serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ku; } } else if (Lng == Lang.AR) { if (serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ar != null) { smsBody = serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ar; } } } _plivoService.SendMessage(recepient.ToList(), smsBody); _dbContext.Entry(appointment).State = EntityState.Modified; appointment.IsAnnounced = true; } catch { } } #endregion _iPAsManager.Delete(serviceSupply.Id, startDateTime); _dbContext.SaveChanges(); appointmentId = appointment.Id; } #endregion #region book appointment for existing user else if (_existUser == true) { var user = await _dbContext.Persons.FirstOrDefaultAsync(u => u.Mobile == patinetModel.Mobile); if (user == null) { throw new EntityNotFoundException(); } // TODO //if (!userManager.IsInRole(user.Id, UsersRoleName.Patient.ToString())) //{ // var assignPatientRole = userManager.AddToRole(user.Id, UsersRoleName.Patient.ToString()); // if (!assignPatientRole.Succeeded) // { // throw new Exception(Messages.ErrorOccuredWhileAssignRole); // } //} if (user.PatientPersonInfo == null) { _dbContext.PatientPersonInfo.Add(new PatientPersonInfo { PersonId = user.Id, CreatedAt = DateTime.Now }); } #region Set Patient Insurance //Check if user already used current insurance name and number int?patientInsuranId = null; if (patinetModel.InsuranceId != 0 && patinetModel.InsuranceNumber != null) { var oldInsurance = user.PatientPersonInfo.PatientInsurances.FirstOrDefault(pi => pi.InsuranceNumber == patinetModel.InsuranceNumber && pi.ServiceSupplyInsuranceId == patinetModel.InsuranceId); if (oldInsurance == null) { var _patientInsurance = new PatientInsurance { UserPatientId = user.Id, ServiceSupplyInsuranceId = patinetModel.InsuranceId, InsuranceNumber = patinetModel.InsuranceNumber, CreatedAt = DateTime.Now }; _dbContext.PatientInsurances.Add(_patientInsurance); _dbContext.SaveChanges(); patientInsuranId = _patientInsurance.Id; } else { patientInsuranId = oldInsurance.Id; } } #endregion var finalBookabeTimePeriods = _doctorServiceManager.CalculateFinalBookableTimePeriods(serviceSupply, startDateTime, polyclinicHealthService); if (finalBookabeTimePeriods == null || finalBookabeTimePeriods.Count() <= 0) { throw new Exception(Messages.ValidEmptyTimePeriodNotFound); } var ipaTimePeriod = finalBookabeTimePeriods.FirstOrDefault(f => f.StartDateTime == startDateTime && f.EndDateTime == endDateTime && f.Type == TimePeriodType.InProgressAppointment); if (ipaTimePeriod == null) { throw new Exception(Messages.ValidEmptyTimePeriodNotFound); } trackingCode = await _appointmentService.GenerateUniqueTrackingNumberAsync(); var appointment = new Appointment { UniqueTrackingCode = trackingCode, Book_DateTime = DateTime.Now, Start_DateTime = startDateTime, End_DateTime = endDateTime, Description = " ", Status = tmpStatus, ServiceSupplyId = serviceSupply.Id, PersonId = user.Id, PatientInsuranceId = patientInsuranId, IsAnnounced = false, Paymentstatus = paymentStatus, IsDeleted = false, ShiftCenterServiceId = polyclinicHealthService.Id, ReservationChannel = channel, CreatedAt = DateTime.Now, OfferId = offerId, RequestLang = requestLang }; _dbContext.Appointments.Add(appointment); _dbContext.SaveChanges(); #region Send SMS notification if (channel != ReservationChannel.Kiosk) { try { var doctor_name = serviceSupply.Person.FullName; var persian_dayOfWeek = Utils.ConvertDayOfWeek(startDateTime.DayOfWeek.ToString()); var day_number = startDateTime.ToShortDateString().Split('/')[2]; var persian_month = Utils.GetMonthName(startDateTime); var year_number = startDateTime.ToShortDateString().Split('/')[0]; var time = startDateTime.ToShortTimeString(); var smsBody = $"{Messages.YourAppointmentForDoctor} { doctor_name} ، { persian_dayOfWeek} { day_number} { persian_month} {year_number} ،{Global.Hour}: {time}"; if (channel == ReservationChannel.ClinicManagerSection) { smsBody = smsBody = "Turn for doctor " + doctor_name + ", " + persian_dayOfWeek + " " + day_number + " " + persian_month + " " + year_number; } string[] recepient = { $"964{patinetModel.Mobile}" }; if (serviceSupply.ShiftCenter.IsIndependent) { if (Lng == Lang.KU) { if (serviceSupply.ShiftCenter.FinalBookSMSMessage_Ku != null) { smsBody = serviceSupply.ShiftCenter.FinalBookSMSMessage_Ku; } } else if (Lng == Lang.AR) { if (serviceSupply.ShiftCenter.FinalBookSMSMessage_Ar != null) { smsBody = serviceSupply.ShiftCenter.FinalBookSMSMessage_Ar; } } } else if (serviceSupply.ShiftCenter.Clinic != null && serviceSupply.ShiftCenter.Clinic.IsIndependent) { if (Lng == Lang.KU) { if (serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ku != null) { smsBody = serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ku; } } else if (Lng == Lang.AR) { if (serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ar != null) { smsBody = serviceSupply.ShiftCenter.Clinic.FinalBookSMSMessage_Ar; } } } else if (serviceSupply.ShiftCenter.Clinic != null && serviceSupply.ShiftCenter.Clinic.Hospital != null) { if (Lng == Lang.KU) { if (serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ku != null) { smsBody = serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ku; } } else if (Lng == Lang.AR) { if (serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ar != null) { smsBody = serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookSMSMessage_Ar; } } } _plivoService.SendMessage(recepient.ToList(), smsBody); _dbContext.Entry(appointment).State = EntityState.Modified; appointment.IsAnnounced = true; } catch { } } #endregion _iPAsManager.Delete(serviceSupply.Id, startDateTime); _dbContext.SaveChanges(); appointmentId = appointment.Id; } #endregion transaction.Commit(); } catch (Exception ex) { transaction.Rollback(); throw ex; } } }); return(new BookingAppointmentResult { Status = BookingAppointmentStatus.Success, Message = Messages.TurnBookedFinally, AppointmentId = appointmentId, TrackingCode = trackingCode }); } catch (Exception ex) { resultMessage = ex.Message; } return(new BookingAppointmentResult { Status = BookingAppointmentStatus.Failure, Message = resultMessage }); }
public async Task <IActionResult> FinalBookTurn(int serviceSupplyId, int centerServiceId, int patientId, DateTime start, DateTime end) { EnsureAllowAccess(serviceSupplyId); try { var serviceSupply = await _serviceSupplyService.GetServiceSupplyByIdAsync(serviceSupplyId); if (serviceSupply == null) { throw new AwroNoreException(Global.Err_DoctorNotFound); } var centerService = _healthServiceService.GetShiftCenterServiceById(centerServiceId); if (centerService == null) { throw new AwroNoreException(NewResource.NotAnyServiceDefinedForThisCenter); } if (!serviceSupply.IsAvailable) { throw new AwroNoreException(serviceSupply.ShiftCenter.Type == ShiftCenterType.BeautyCenter ? Global.BeautyCenterNotActive : Global.DoctorNotActive); } var patient = await _patientService.GetByIdAsync(patientId); if (patient == null) { throw new AwroNoreException("Patient Not Found"); } var person = patient.Person ?? throw new AwroNoreException("Person Not Found"); // Check if this patient has reserved appointment today or not? if (_appointmentsManager.HaveAppointmentForDate(start.ToShortDateString(), person.Mobile, serviceSupplyId, centerServiceId)) { throw new AwroNoreException(Global.Err_UserHaveTurnForDate); } // Reserve Turn In In-Progress Appointments var emptyPeriods = _doctorServiceManager.Calculate_Available_Empty_TimePeriods_By_Percent(serviceSupply, start, centerService); if (emptyPeriods == null || !emptyPeriods.Any()) { throw new AwroNoreException(NewResource.TurnReservedBeforeByAnotherPerson); } var emptyTurn = emptyPeriods.FirstOrDefault(x => x.StartDateTime == start && x.EndDateTime == end); if (emptyTurn == null) { throw new AwroNoreException(NewResource.TurnReservedBeforeByAnotherPerson); } var ipa = new IPAModel { AddedAt = DateTime.Now, ServiceSupplyId = serviceSupplyId, StartDateTime = emptyTurn.StartDateTime, EndDateTime = emptyTurn.EndDateTime, UserHostAgent = "Stand-WPF", IsForSelectedDoctor = false, PolyclinicHealthService = centerService, OfferId = null }; if (_doctorServiceManager.IsAvailableEmptyTimePeriod(ipa.ServiceSupplyId, ipa.StartDateTime, ipa.EndDateTime, ipa.PolyclinicHealthService)) { _iPAsManager.Insert(ipa); } else { throw new Exception(Global.Err_ValidTimePeriodNotFound); } var patientModel = new PatientModel { Mobile = person.Mobile, }; var bookAppoint = await _appointmentsManager.BookAppointmentAsync(serviceSupply, patientModel, start.ToShortDateString(), start.ToString("HH:mm"), end.ToString("HH:mm"), true, PaymentStatus.Free, centerService, ReservationChannel.ClinicManagerSection, requestLang : Lng, offerId : null); return(Json(new { success = bookAppoint.Status == BookingAppointmentStatus.Success, message = bookAppoint.Message })); } catch (Exception e) { try { _iPAsManager.Delete(serviceSupplyId, start); } catch { // IGNORED } throw e; } }
public async Task <IActionResult> FinalBookTurn([FromBody] FinalBookTurnDTO model) { if (string.IsNullOrEmpty(CurrentUserName)) { return(Unauthorized()); } var mobile = CurrentUserName; // Check if this patient has reserved appointment today or not? if (_appointmentsManager.HaveAppointmentForDate(model.Date, mobile, model.ServiceSupplyId, model.CenterServiceId)) { throw new AwroNoreException(Global.Err_UserHaveTurnForDate); } // Save Requested Turn if (model.IsRequested) { var(trackingCode, appointmentId) = await _appointmentsManager.CreateRequestedAppointmentAsync(mobile, model, requestLang : RequestLang); var result = new FinalBookTurnResultDTO { IsSucceeded = true, IsRequested = true, Message = "داواکاری نۆرەکەتان بە سەرکەوتوویی تۆمار کرا", Description = "This is just request", TurnId = appointmentId, TrackingCode = trackingCode }; return(Ok(result)); } else { var offerCode = string.Empty; var turnDate = DateTime.Parse(model.Date); var turnStartDateTime = DateTime.Parse($"{model.Date} {model.StartTime}"); var turnEndDateTime = DateTime.Parse($"{model.Date} {model.EndTime}"); var serviceSupply = await _serviceSupplyService.GetServiceSupplyByIdAsync(model.ServiceSupplyId); if (serviceSupply == null) { throw new AwroNoreException(Global.Err_DoctorNotFound); } var centerService = _servicesService.GetShiftCenterServiceById(model.CenterServiceId); if (centerService == null) { throw new AwroNoreException(NewResource.NotAnyServiceDefinedForThisCenter); } if (!serviceSupply.IsAvailable) { throw new AwroNoreException(serviceSupply.ShiftCenter.Type == ShiftCenterType.BeautyCenter ? Global.BeautyCenterNotActive : Global.DoctorNotActive); } if (_blockedMobileService.IsMobileBlocked(serviceSupply.ShiftCenterId, mobile)) { throw new AwroNoreException(Global.Err_MobileBlocked); } try { // Ensure that user don't have another appointment with same time await _appointmentsManager.EnsureNotHaveSameTimeAppointmentAsync(turnStartDateTime, mobile); // Reserve Turn In In-Progress Appointments var emptyPeriods = _doctorServiceManager.Calculate_Available_Empty_TimePeriods_By_Percent(serviceSupply, turnDate, centerService); if (emptyPeriods == null || !emptyPeriods.Any()) { throw new AwroNoreException(NewResource.TurnReservedBeforeByAnotherPerson); } var emptyTurn = emptyPeriods.FirstOrDefault(x => x.StartDateTime == turnStartDateTime && x.EndDateTime == turnEndDateTime); if (emptyTurn == null) { throw new AwroNoreException(NewResource.TurnReservedBeforeByAnotherPerson); } var ipa = new IPAModel { AddedAt = DateTime.Now, ServiceSupplyId = model.ServiceSupplyId, StartDateTime = emptyTurn.StartDateTime, EndDateTime = emptyTurn.EndDateTime, UserHostAgent = "Stand-WPF", IsForSelectedDoctor = false, PolyclinicHealthService = centerService, OfferId = model.OfferId }; if (_doctorServiceManager.IsAvailableEmptyTimePeriod(ipa.ServiceSupplyId, ipa.StartDateTime, ipa.EndDateTime, ipa.PolyclinicHealthService)) { if (model.OfferId != null) { var offer = await _offerRepository.GetByIdAsync(model.OfferId.Value); if (offer == null) { throw new AwroNoreException("Offer Not Found"); } offerCode = offer.Code; var offerAllTimePeriods = _doctorServiceManager.CalculateAllTimePeriodsForOffer(offer); if (offerAllTimePeriods == null) { throw new AwroNoreException("Empty Turns Not Found"); } var isEmptyOffer = offerAllTimePeriods.Any(x => x.Type == TimePeriodType.EmptyOffer && x.StartDateTime == turnStartDateTime && x.EndDateTime == turnEndDateTime); if (!isEmptyOffer) { throw new AwroNoreException("All Offer Appointments Are Reserved"); } } _iPAsManager.Insert(ipa); } else { throw new Exception(Global.Err_ValidTimePeriodNotFound); } var currentUser = await _userService.GetPersonByMobileAsync(mobile); var patientModel = new PatientModel { Mobile = mobile, }; string message = string.Empty; var queueNumber = -1; var bookAppoint = await _appointmentsManager.BookAppointmentAsync(serviceSupply, patientModel, model.Date, model.StartTime, model.EndTime, true, PaymentStatus.Free, centerService, ReservationChannel.MobileApplication, requestLang : RequestLang, offerId : model.OfferId); if (bookAppoint.Status == BookingAppointmentStatus.Success) { try { var appointment = _appointmentService.GetAppointmentById((int)bookAppoint.AppointmentId); try { logger.Info("Begin try to send notification..."); var polyclinic = serviceSupply.ShiftCenter; var instanceIds = new List <string>(); if (polyclinic.FcmInstanceIds != null && polyclinic.FcmInstanceIds.Count() > 0) { instanceIds = polyclinic.FcmInstanceIds.Where(x => x.IsOn).Select(x => x.FcmId).ToList(); } if (instanceIds.Count > 0) { var patientName = appointment.Person.FullName; var date = appointment.Start_DateTime.ToShortDateString(); var title = "New Turn!"; var text = patientName + " reserved turn for " + date; foreach (var item in instanceIds) { await _notificationService.SendFcmToSingleDeviceAsync(item, title, text); } } } catch (Exception e) { logger.Error("Error sending notification..."); logger.Error(e.Message); logger.Error(e.InnerException); } queueNumber = _appointmentService.GetQueueNumberForAppointment(serviceSupply.Id, appointment.Id, centerService.Id, appointment.Start_DateTime); if (serviceSupply.ShiftCenter.IsIndependent) { if (serviceSupply.ShiftCenter.FinalBookMessage_Ku != null) { message = serviceSupply.ShiftCenter.FinalBookMessage_Ku; } } else if (serviceSupply.ShiftCenter.Clinic.IsIndependent) { if (serviceSupply.ShiftCenter.Clinic.FinalBookMessage_Ku != null) { message = serviceSupply.ShiftCenter.Clinic.FinalBookMessage_Ku; } } else if (serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookMessage_Ku != null) { message = serviceSupply.ShiftCenter.Clinic.Hospital.FinalBookMessage_Ku; } } catch { } } var result = new FinalBookTurnResultDTO { IsSucceeded = bookAppoint.Status == BookingAppointmentStatus.Success, Message = bookAppoint.Message, TurnId = (int)bookAppoint.AppointmentId, QueueNumber = queueNumber, TrackingCode = bookAppoint.TrackingCode, OfferCode = offerCode }; return(Ok(result)); } catch (Exception e) { try { _iPAsManager.Delete(model.ServiceSupplyId, turnStartDateTime); } catch { // IGNORED } if (e is AwroNoreException) { return(Ok(new FinalBookTurnResultDTO { IsSucceeded = false, Message = e.Message })); } throw e; } } }