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;
            }
        }
Exemple #3
0
        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;
                }
            }
        }