public ActionResult Create()
        {
            PagoVM pagoVM = new PagoVM();
            pagoVM.PayCenterId = PayCenterId;
            EstadoCuentaBR br = new EstadoCuentaBR();
            if (PayCenterId > 0)
            {
                var saldo = br.GetSaldosPagoServicio(PayCenterId);
                ViewData["Eventos"] = saldo.EventosDisponibles;
                ViewData["SaldoActual"] = saldo.SaldoActual.ToString("C");
                ViewData["SaldoDisponible"] = saldo.SaldoDisponible;
                ViewData["SaldoDisponibleString"] = saldo.SaldoDisponible.ToString("C");

                var comisionFinanciamiento = br.GetComisionFinanciamiento(PayCenterId);
                ViewData["Comision"] = comisionFinanciamiento.Comision;
                ViewData["ComisionString"] = comisionFinanciamiento.Comision.ToString("C");
                //Le resto lo que tiene como saldo negativo al máximo a financiar.
                ViewData["MaximoFinanciar"] = saldo.SaldoDisponible < 0 ? comisionFinanciamiento.Financiamiento + saldo.SaldoDisponible : comisionFinanciamiento.Financiamiento;
            }
            return View(pagoVM);
        }
        public ActionResult Create(PagoVM model)
        {
            if (PayCenterId == 0)
            {
                model.PayCenterName = string.Empty;
                AddValidationMessage(enumMessageType.DataValidation, "Por favor, seleccione primero un PayCenter.");
                return View(model);
            }

            EstadoCuentaBR br = new EstadoCuentaBR(repository.context);
            var saldo = br.GetSaldosPagoServicio(PayCenterId);
            ViewData["SaldoActual"] = saldo.SaldoActual.ToString("C");
            ViewData["SaldoDisponible"] = saldo.SaldoDisponible.ToString("C");
            ViewData["Eventos"] = saldo.EventosDisponibles;

            if (model.Importe <= 0)
            {
                AddValidationMessage(enumMessageType.DataValidation, "El importe no puede ser menor a $0.00.");
                return View(model);
            }
            if (ModelState.IsValid)
            {

                #region Crear Movimiento Inicial
                Pago pago = new Pago();
                PaycenterBR payCenterBR = new PaycenterBR();
                var cuentaId = payCenterBR.GetOrCreateCuentaPayCenter(PayCenterId, enumTipoCuenta.Pago_de_Servicios, PROVEEDOR_EVOLUCIONAMOVIL);
                //Devuelve si usa evento en el pago
                bool usaEvento = false;
                List<Movimiento> movimientos = br.CrearMovimientosPagoServicios(PayCenterId, (Decimal)model.Importe, PayCenterName, out usaEvento);
                Succeed = br.Succeed;
                ValidationMessages = br.ValidationMessages;

                if (!Succeed)
                {
                    return View(model);
                }

                #endregion

                #region Registro de Pago
                string Referencia = "";
                Mapper.CreateMap<PagoVM, Pago>().ForMember(dest => dest.DetallePagos, opt => opt.Ignore());
                Mapper.Map(model, pago);
                pago.Servicio = model.Servicios.Where(x => x.Value == model.ServicioId).FirstOrDefault().Text;
                pago.PayCenterId = PayCenterId;
                pago.Movimiento = movimientos.Where(x => x.Motivo == (short)enumMotivo.Pago).First();
                pago.UsoEvento = usaEvento;

                var iDetalles = serviciosRepository.LoadDetallesServicioByServicioID(pago.ServicioId);
                foreach (DetalleServicio d in iDetalles)
                {
                    var valor = Request.Form[d.DetalleServicioId.ToString()];
                    if (d.EsReferencia)
                        Referencia = valor;

                    pago.DetallePagos.Add(new DetallePago { Campo = d.Campo, Valor = valor });
                }

                repository.Add(pago);
                repository.Save();
                //Actualizo el Id de referencia del Pago en los movimientos correspondientes
                br.ActualizaReferenciaIdMovimiento(pago.MovimientoId, pago.PagoId);
                repository.Save();

                model.PagoId = pago.PagoId;
                #endregion

                #region Registro Ticket
                try
                {

                    //Verifica si tiene configurada la comisión que mostrará al cliente, se toma el valor para mostrar en el ticket
                    ParametrosRepository parametrosRepository = new ParametrosRepository();
                    var parametrosPayCenter = parametrosRepository.GetParametrosPayCenter(PayCenterId);
                    var parametrosGlobales = parametrosRepository.GetParametrosGlobales();

                    Ticket ticket = new Ticket();
                    ticket.ClienteEmail = "";
                    ticket.ClienteNombre = pago.ClienteNombre;
                    ticket.ClienteTelefono = "";
                    ticket.Comision = (parametrosPayCenter != null && parametrosPayCenter.ComisionCliente != null ? (Decimal)parametrosPayCenter.ComisionCliente : 0); //Comision configurada del paycenter
                    ticket.FechaCreacion = DateTime.UtcNow.GetCurrentTime();
                    ticket.Folio = createFolio(pago.PagoId);
                    ticket.Importe = pago.Importe;
                    ticket.Leyenda = parametrosGlobales != null ? parametrosGlobales.LeyendaTicket : null;
                    ticket.PagoId = pago.PagoId;
                    ticket.PayCenterId = pago.PayCenterId;
                    ticket.TipoServicio = pago.Servicio;
                    ticket.Referencia = Referencia;
                    ticket.PayCenterName = PayCenterName;
                    ticket.FechaVencimiento = pago.FechaVencimiento;

                    tRepository.Add(ticket);
                    Succeed = tRepository.Save();
                    if (!Succeed)
                    {
                        AddValidationMessage(enumMessageType.UnhandledException, "Su pago ha sido Registrado con éxito. Sin embargo, no se pudo generar el ticket, favor de comunicarse con un ejecutivo. ");
                    }

                    //Ejecuta el envío de correo de forma asíncrona
                    EnviarTicketDelegate enviarDelegate = new EnviarTicketDelegate(EnviarTicketEmail);
                    var result = enviarDelegate.BeginInvoke(pago,null, null);

                    return RedirectToAction("Ticket/" + ticket.PagoId.ToString());
                }
                catch (Exception ex)
                {
                    AddValidationMessage(enumMessageType.UnhandledException, "Su pago ha sido Registrado con éxito. Sin embargo, no se pudo generar el ticket, favor de comunicarse con un ejecutivo. ");
                    return View(model);
                }

                #endregion

            }
            else
            {
                AddValidationMessage(enumMessageType.BRException, "Los datos no son válidos");
            }
            return View(model);
        }
        public ViewResult Details(PagoVM model)
        {
            //Aquí van las acciones del PayCenter y Staf para el depósito
            var id = model.PagoId;
            var action = model.CambioEstatusVM.Estatus;
            string comentario = model.CambioEstatusVM.Comentario != null ? model.CambioEstatusVM.Comentario.TrimEnd() : null;
            Pago pago = repository.ListAll().Where(x => x.PagoId == model.PagoId).FirstOrDefault();
            //Reinicio el ModelState porque no valido sus valores
            ModelState.Clear();

            if (id > 0)
            {
                var movimiento = pago.Movimiento;

                //validar que exista el moviento y sino mandar mensaje de error
                if (movimiento != null)
                {
                    EstadoCuentaBR estadoCuentaBR = new EstadoCuentaBR(repository.context);
                    //Asigno valor default en caso de que entre en ningún case de switch
                    enumEstatusMovimiento nuevoEstatus = (enumEstatusMovimiento)movimiento.Status;
                    switch (action)
                    {
                        case "Cancelar":
                            nuevoEstatus = enumEstatusMovimiento.Cancelado;
                            break;
                        case "Aplicar":
                            nuevoEstatus = enumEstatusMovimiento.Aplicado;
                            break;
                        case "Rechazar":
                            nuevoEstatus = enumEstatusMovimiento.Rechazado;
                            break;
                    }

                    movimiento = estadoCuentaBR.ActualizarMovimiento(pago.MovimientoId, nuevoEstatus, comentario);
                    Succeed = estadoCuentaBR.Succeed;
                    ValidationMessages = estadoCuentaBR.ValidationMessages;

                    if (Succeed)
                    {
                        pago.Status = movimiento.Status;
                        Succeed = repository.Save();
                        if (Succeed)
                        {
                            ModelState.Clear();
                            AddValidationMessage(enumMessageType.Succeed, "El reporte de depósito ha sido " + nuevoEstatus.ToString() + " correctamente");
                            var paycenter = pRepository.LoadById(pago.PayCenter.PayCenterId);
                            if (paycenter != null)
                            {
                                //Ejecuta el envío de correo de forma asíncrona
                                EnviarCambioEstatusDelegate enviarDelegate = new EnviarCambioEstatusDelegate(EnviarCambioEstatusEmail);
                                var result = enviarDelegate.BeginInvoke(nuevoEstatus, pago,paycenter, null, null);
                                EnviarCambioEstatusEmail(nuevoEstatus, pago, paycenter);
                            }
                            //No obtuve lo errores por que es una clase estática y va a almacenar los de todas las sesiones
                            //ValidationMessages.AddRange(EmailHelper
                            //AddValidationMessage(enumMessageType.Notification, "No pudo enviarse el email de aviso. Comuníquelo al administrador");
                            //return Details(id);
                        }
                        else
                        {
                            //TODO: implemtar código que traiga mensajes del repositorio
                        }
                    }

                }
                else
                {
                    AddValidationMessage(enumMessageType.BRException, "No se encontró el movimiento para el depósito.");
                }

            }
            else
            {
                AddValidationMessage(enumMessageType.BRException, "No existe el depósito.");
            }

            return Details(id);
        }
        private PagoVM FillPagoVM(Int32 id)
        {
            PagoVM pagoVM = new PagoVM();
            try
            {
                Pago pago = repository.LoadById(id);
                if (pago == null)
                {
                    return null;
                }

                //Me aseguro de obtener el pago tal y como estaba en la BD y sin cambios
                repository.context.Refresh(System.Data.Objects.RefreshMode.StoreWins, pago);

                Mapper.CreateMap<Pago, PagoVM>().ForMember(dest => dest.Servicios, opt => opt.Ignore());
                Mapper.Map(pago, pagoVM);
                pagoVM.PayCenterName = pago.PayCenter.Nombre;
                pagoVM.ServicioNombre = pagoVM.Servicios.Where(x => x.Value == pago.ServicioId).FirstOrDefault().Text;

                foreach (Movimientos_Estatus m in pago.Movimiento.Movimientos_Estatus.OrderByDescending(x => x.Movimiento_EstatusId))
                {
                    HistorialEstatusVM h = new HistorialEstatusVM();
                    h.Comentarios = m.Comentarios;
                    h.Estatus = ((enumEstatusMovimiento)m.Status).ToString();
                    h.Fecha = m.FechaCreacion.GetCurrentTime().ToShortDateString();
                    h.UserName = m.UserName;
                    pagoVM.HistorialEstatusVM.Add(h);
                }
            }
            catch (Exception e)
            {
                AddValidationMessage(enumMessageType.BRException, "Ocurrio un error al recuperar la información del pago: " + e.Message);
            }
            return pagoVM;
        }
        public ViewResult Details(int id)
        {
            PagoVM pagoVM;
            bool isValid = true;
            if (User.IsInRole(enumRoles.PayCenter.ToString()))
            {
                isValid = repository.IsAuthorized(PayCenterId, id);
            }
            if (!isValid)
            {
                AddValidationMessage(enumMessageType.BRException, "No tiene autorización para este pago.");
                pagoVM = new PagoVM();
                pagoVM.FechaVencimiento = Convert.ToDateTime("01/01/1999");
                return View(pagoVM);
            }
            pagoVM = FillPagoVM(id);
            if (pagoVM == null)
            {
                Response.Redirect("PagoServicios", true);
                return View("Index");
            }
            int RoleUser = GetRolUser(HttpContext.User.Identity.Name);
            ViewBag.Role = RoleUser;

            return View(pagoVM);
        }