/// <summary>
        /// Update the appointment
        /// </summary>
        /// <param name="appointment">appointment</param>
        /// <returns></returns>
        public Response <AppointmentModel> UpdateAppointment(AppointmentModel appointment)
        {
            var response = new Response <AppointmentModel>();

            response.DataItems = new List <AppointmentModel>();

            if (appointment.Recurrence != null && appointment.Recurrence.IsRecurring && appointment.IsRecurringAptEdit)
            {
                using (var transactionScope = unitOfWork.BeginTransactionScope())
                {
                    try
                    {
                        // NOTE: when cancelling the recurrence, the sp will cancel all the appointments in the recurrence
                        if (appointment.RecurrenceID != null ||
                            (appointment.RecurrenceID == null && appointment.Recurrence != null))
                        {
                            // Delete by recurrene id
                            if (appointment.RecurrenceID != null)
                            {
                                DeleteAppointmentsByRecurrence((long)appointment.RecurrenceID);
                            }
                            else if (appointment.Recurrence.RecurrenceID != 0)
                            {
                                DeleteAppointmentsByRecurrence(appointment.Recurrence.RecurrenceID);
                            }
                            else
                            {
                                DeleteAppointment(appointment.AppointmentID, DateTime.Now);
                            }

                            //if (appointment.Recurrence.IsRecurring && appointment.RecurrenceID != null)
                            //    _recurrenceDataProvider.UpdateRecurrence(appointment.Recurrence);
                            //else
                            //{
                            //    var recurrenceID = _recurrenceDataProvider.AddRecurrence(appointment.Recurrence);
                            //    appointment.RecurrenceID = recurrenceID;
                            //    if (recurrenceID != null) appointment.Recurrence.RecurrenceID = (long)recurrenceID;
                            //}

                            // Create a new recurrence every time, this way if the recurrence update results in removing
                            // future appts and leaving priors in the back there will be a different recurrence id for each one
                            var recurrenceID = _recurrenceDataProvider.AddRecurrence(appointment.Recurrence);
                            appointment.RecurrenceID = recurrenceID;
                            if (recurrenceID != null)
                            {
                                appointment.Recurrence.RecurrenceID = (long)recurrenceID;
                            }
                        }
                        else
                        {
                            DeleteAppointment(appointment.AppointmentID, DateTime.Now);
                            var recurrenceID = _recurrenceDataProvider.AddRecurrence(appointment.Recurrence);
                            appointment.RecurrenceID = recurrenceID;
                            if (recurrenceID != null)
                            {
                                appointment.Recurrence.RecurrenceID = (long)recurrenceID;
                            }
                        }

                        var recurrenceCalculator = new RecurrenceCalculator(appointment);
                        var apptsToAdd           = recurrenceCalculator.GetAppts();

                        // delete the future appointments and recreate new appointments
                        apptsToAdd.ForEach(appt =>
                        {
                            // we only want to update/cancel future appointments
                            if (appt.AppointmentDate >= DateTime.Now)
                            {
                                var appointmentParameters = BuildAppointmentSpParams(appt, false);
                                var appointmentRepository = unitOfWork.GetRepository <AppointmentModel>(SchemaName.Scheduling);

                                var apptWithID = unitOfWork.EnsureInTransaction(appointmentRepository.ExecuteNQStoredProc, "usp_AddAppointment", appointmentParameters,
                                                                                forceRollback: appointment.ForceRollback.GetValueOrDefault(false), idResult: true);

                                // if any of the creation of appointments fail, rollback, and return a response indicating what failed
                                if (apptWithID.ResultCode != 0)
                                {
                                    return;
                                }
                                else
                                {
                                    appt.AppointmentID = apptWithID.ID;
                                }
                            }
                        });

                        response.DataItems = apptsToAdd;

                        // no errors creating any appointments, so lock in all appointments created
                        if (!appointment.ForceRollback.GetValueOrDefault(false))
                        {
                            unitOfWork.TransactionScopeComplete(transactionScope);
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.Error(ex);
                        response.ResultCode    = -1;
                        response.ResultMessage = "Error while saving the user's profile";
                    }
                }
            }
            else if (appointment.Recurrence != null && !appointment.Recurrence.IsRecurring && appointment.IsRecurringAptEdit) // appoint is being switched to a non-recurring appointment
            {
                if (appointment.RecurrenceID != null)
                {
                    DeleteAppointmentsByRecurrence((long)appointment.RecurrenceID);
                }

                if (!appointment.Recurrence.IsRecurring && appointment.RecurrenceID != null)
                {
                    appointment.RecurrenceID = null;
                    appointment.Recurrence   = null;
                }

                var appointmentParameters = BuildAppointmentSpParams(appointment, false);
                var appointmentRepository = unitOfWork.GetRepository <AppointmentModel>(SchemaName.Scheduling);
                var resp = appointmentRepository.ExecuteNQStoredProc("usp_AddAppointment", appointmentParameters, idResult: true);
                appointment.AppointmentID = resp.ID;
                response.DataItems.Add(appointment);
            }
            else
            {
                var appointmentParameters = BuildAppointmentSpParams(appointment, true);
                appointmentParameters.Add(new SqlParameter("ModifiedBy", AuthContext.Auth.User.UserID));
                var appointmentRepository = unitOfWork.GetRepository <AppointmentModel>(SchemaName.Scheduling);
                response = appointmentRepository.ExecuteStoredProc("usp_UpdateAppointment", appointmentParameters);
                response.DataItems.Add(appointment);
            }

            return(response);
        }
        /// <summary>
        /// Adds the appointment
        /// </summary>
        /// <param name="appointment">appointment</param>
        /// <returns></returns>
        public Response <AppointmentModel> AddAppointment(AppointmentModel appointment)
        {
            var response = new Response <AppointmentModel>();

            response.DataItems = new List <AppointmentModel>();

            if (appointment.Recurrence != null && appointment.Recurrence.IsRecurring)
            {
                appointment.RecurrenceID = _recurrenceDataProvider.AddRecurrence(appointment.Recurrence);

                var recurrenceCalculator = new RecurrenceCalculator(appointment);
                var appts = recurrenceCalculator.GetAppts();

                if (appts.Count > 0)
                {
                    using (var transactionScope = unitOfWork.BeginTransactionScope())
                    {
                        try
                        {
                            appts.ForEach(appt =>
                            {
                                var appointmentParameters = BuildAppointmentSpParams(appt, false);
                                var appointmentRepository =
                                    unitOfWork.GetRepository <AppointmentModel>(SchemaName.Scheduling);

                                var apptWithID =
                                    unitOfWork.EnsureInTransaction(appointmentRepository.ExecuteNQStoredProc,
                                                                   "usp_AddAppointment", appointmentParameters,
                                                                   forceRollback: appointment.ForceRollback.GetValueOrDefault(false),
                                                                   idResult: true);

                                // if any of the creation of appointments fail, rollback, and return a response indicating what failed
                                if (apptWithID.ResultCode != 0)
                                {
                                    return;
                                }
                                else
                                {
                                    appt.AppointmentID = apptWithID.ID;
                                }
                            });

                            response.DataItems = appts;
                            response.ID        = appts.Min(x => x.AppointmentID);

                            // no errors creating any appointments, so lock in all appointments created
                            if (!appointment.ForceRollback.GetValueOrDefault(false))
                            {
                                unitOfWork.TransactionScopeComplete(transactionScope);
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.Error(ex);
                            response.ResultCode    = -1;
                            response.ResultMessage = "Error while saving the user's profile";
                        }
                    }
                }
            }
            else
            {
                var appointmentParameters = BuildAppointmentSpParams(appointment, false);
                var appointmentRepository = unitOfWork.GetRepository <AppointmentModel>(SchemaName.Scheduling);
                var appointmentResponse   = appointmentRepository.ExecuteNQStoredProc("usp_AddAppointment", appointmentParameters, idResult: true);
                response.ID = appointment.AppointmentID = appointmentResponse.ID;
                response.DataItems.Add(appointment);
            }

            return(response);
        }