public ActionResult ReservaOrganizador(ReservaOrganizadorModel model)
        {
            using (var context = new inf245netsoft())
            {
                try
                {
                    for (int i = 0; i < model.idFuncion.Length; i++) if (model.eliminar[i])
                        {
                            if (model.idAsiento[i] < 0)
                            {
                                var ZXF = context.ZonaxFuncion.Find(model.idFuncion[i], model.idZona[i]);
                                ZXF.cantReservaOrganizador--;
                                ZXF.cantLibres++;
                            }
                            else
                            {
                                var asientoReal = context.AsientosXFuncion.Find(model.idAsiento[i], model.idFuncion[i]);
                                asientoReal.estado = "libre";
                            }
                        }
                    context.SaveChanges();
                }
                catch (OptimisticConcurrencyException ex)
                {
                    TempData["tipo"] = "alert alert-warning";
                    TempData["message"] = "No se pudieron cancelar las reservas";
                    Redirect("~/Evento/verReservaOrganizador?evento=" + model.idEvento);
                }
            }

            TempData["tipo"] = "alert alert-success";
            TempData["message"] = "Las reservas se cancelaron correctamente";
            return Redirect("~/Evento/verReservaOrganizador?evento=" + model.idEvento);
        }
        public string reservarOrganizador(PaqueteEntradas paquete)
        {
            try
            {
                using (var context = new inf245netsoft())
                {
                    try
                    {
                        if (paquete.tieneAsientos)
                        {
                            for (int i = 0; i < paquete.cantEntradas; i++)
                            {
                                int col = paquete.columnas[i];
                                int fil = paquete.filas[i];
                                List<Asientos> listasiento = context.Asientos.Where(x => x.codZona == paquete.idZona && x.fila == fil && x.columna == col).ToList();
                                AsientosXFuncion actAsiento = context.AsientosXFuncion.Find(listasiento.First().codAsiento, paquete.idFuncion);
                                actAsiento.estado = "RESERVAORGANIZADOR";
                            }
                        }
                        else
                        {
                            ZonaxFuncion ZXF = context.ZonaxFuncion.Find(paquete.idFuncion, paquete.idZona);
                            if (ZXF.cantLibres < paquete.cantEntradas) return "No hay suficientes entradas";
                            ZXF.cantLibres -= paquete.cantEntradas;
                            ZXF.cantReservaOrganizador += paquete.cantEntradas;
                        }
                        context.SaveChanges();
                    }
                    catch (OptimisticConcurrencyException ex)
                    {
                        return "No se pudieron reservar los asientos, alguien más ya lo hizo.";
                    }

                }
            }
            catch (Exception ex)
            {
                return "Ocurrio un error inesperado.";
            }
            //Funciones Utilitarias necesarias
            //BuscarEntradasLeQuedan( User , Funcion )
            return "Ok";
        }
        public ActionResult VenderEntrada(VenderEntradaModel model)
        {
            if (Session["CarritoItemVentas"] != null)
            {
                if (validacionVenta(model))
                {
                    if (verificaSiCompra(model.idFunciones, model.Dni))
                    {
                        int idVenta = 0;
                        DateTime hoy = DateTime.Now;
                        CuentaUsuario cuenta = new CuentaUsuario();
                        using (var context = new inf245netsoft())
                        {
                            try
                            {
                                List<CarritoItem> carrito = (List<CarritoItem>)Session["CarritoItemVentas"];
                                Ventas ve = new Ventas();
                                int cantidadEntradasTotales = carrito.Sum(c => c.cantidad);
                                try
                                {//si es un usuario registrado busco la cuenta y la asigno luego a la venta
                                    cuenta = context.CuentaUsuario.Where(c => c.codDoc.CompareTo(model.Dni) == 0).First();
                                }
                                catch (Exception ex)
                                {//si no es un cliente registrado guardo la venta como si fuera anonima
                                    cuenta = context.CuentaUsuario.Find(MagicHelpers.AnonimoUniversal);
                                }
                                ve.fecha = DateTime.Now;
                                ve.cantAsientos = cantidadEntradasTotales;
                                //de todas maneras en la venta se registra el nombre, dni y tipo de documento del que esta comprando.
                                ve.cliente = model.Nombre;
                                ve.CuentaUsuario = cuenta;
                                ve.codDoc = model.Dni;
                                //--
                                ve.Estado = MagicHelpers.Compra;
                                ve.tipoDoc = 1;
                                ve.montoEfectivoDolares = model.MontoDolares;
                                ve.MontoTotalSoles = model.MontoPagar;
                                ve.montoCreditoSoles = model.MontoTar;
                                double dolarsoles = (double)model.MontoDolares * db.TipoDeCambio.Where(c => c.estado == "Activo").ToList().Last().valor.Value / MagicHelpers.ConstanteTipoCambio;
                                if (model.MontoEfe > dolarsoles)
                                {
                                    ve.montoEfectivoSoles = model.MontoEfe - model.Vuelto;
                                }
                                else
                                {
                                    ve.montoEfectivoSoles = model.MontoEfe;
                                    ve.montoEfectivoDolares = (dolarsoles - model.Vuelto) / (db.TipoDeCambio.Where(c => c.estado == "Activo").ToList().Last().valor.Value / MagicHelpers.ConstanteTipoCambio);
                                }
                                //--vendedor, guardo el correo del vendedor en la venta
                                ve.vendedor = User.Identity.Name;
                                //
                                if (model.MontoTar > 0 && model.MontoEfe == 0)
                                {//para compra solo en tarjeta
                                    ve.modalidad = "T";
                                }
                                if (model.MontoEfe > 0 && model.MontoTar > 0)
                                {//mixto
                                    ve.modalidad = "M";
                                }
                                if (model.MontoTar == 0)
                                {//solo efectivo
                                    ve.modalidad = "E";
                                }
                                context.Ventas.Add(ve);
                                try
                                {
                                    context.SaveChanges();
                                    idVenta = ve.codVen;
                                }
                                catch (DbEntityValidationException dbEx)
                                {
                                    foreach (var validationErrors in dbEx.EntityValidationErrors)
                                    {
                                        foreach (var validationError in validationErrors.ValidationErrors)
                                        {
                                            Trace.TraceInformation("Property: {0} Error: {1}",
                                                                    validationError.PropertyName,
                                                                    validationError.ErrorMessage);
                                        }
                                    }
                                }
                                //para cada item del carrito
                                for (int w = 0; w < carrito.Count; w++)
                                {
                                    CarritoItem paquete = carrito[w];
                                    //zona del evento
                                    ZonaEvento zo = context.ZonaEvento.Find(paquete.idZona);
                                    //en que perdiodo de venta estamos
                                    PeriodoVenta per = context.PeriodoVenta.Where(c => c.codEvento == paquete.idEvento && c.fechaInicio <= hoy && c.fechaFin >= hoy).ToList().First();
                                    PrecioEvento pr = context.PrecioEvento.Where(c => c.codZonaEvento == paquete.idZona && c.codPeriodoVenta == per.idPerVent).ToList().First();
                                    //la venta x funcion requerida
                                    VentasXFuncion vf = new VentasXFuncion();
                                    //si ya existe una venta x funcion de esta venta
                                    if (context.VentasXFuncion.Any(c => c.codVen == ve.codVen && c.codFuncion == paquete.idFuncion))
                                    {
                                        vf = context.VentasXFuncion.Where(c => c.codVen == ve.codVen && c.codFuncion == paquete.idFuncion).First();
                                        vf.cantEntradas += paquete.cantidad;
                                        vf.subtotal += paquete.cantidad * pr.precio;
                                        float? porcDescuento = 0;
                                        //default es para pago mixto
                                        vf.descuento += (int)model.Descuento;
                                        //vuelvo a modificar los descuentos si es tarjeta o efectivo
                                        if (ve.modalidad == "T")
                                        {
                                            if (model.idPromociones[w] != -1)
                                            {
                                                int idPromocion = model.idPromociones[w];
                                                Promociones promocion = context.Promociones.Where(c => c.codPromo == idPromocion && c.codEvento == paquete.idEvento).First();
                                                porcDescuento = promocion.descuento / 100;
                                            }
                                            vf.descuento = (int?)(vf.subtotal * porcDescuento);
                                        }
                                        if (ve.modalidad == "E")
                                        {
                                            vf.descuento = (int?)model.Descuento;
                                        }
                                        vf.total += vf.subtotal - vf.descuento;
                                    }
                                    else
                                    {
                                        //creo una nueva ventaxfuncion
                                        vf.codVen = ve.codVen;
                                        vf.cantEntradas = paquete.cantidad;
                                        vf.codFuncion = paquete.idFuncion;
                                        vf.Ventas = ve;
                                        vf.Funcion = context.Funcion.Find(paquete.idFuncion);
                                        vf.hanEntregado = false;
                                        vf.subtotal = paquete.cantidad * pr.precio;
                                        float? porcDescuento = 0;
                                        //default es para pago mixto
                                        vf.descuento = (int)model.Descuento;
                                        //solo registro la promocion si es una venta solo con tarjeta o solo con efectivo
                                        if (ve.modalidad == "T")
                                        {
                                            if (model.idPromociones[w] != -1)
                                            {
                                                int idPromocion = model.idPromociones[w];
                                                Promociones promocion = context.Promociones.Where(c => c.codPromo == idPromocion && c.codEvento == paquete.idEvento).First();
                                                porcDescuento = promocion.descuento / 100;
                                            }
                                            vf.descuento = (int?)(vf.subtotal * porcDescuento);
                                        }
                                        if (ve.modalidad == "E")
                                        {
                                            vf.descuento = (int?)model.Descuento;
                                        }
                                        vf.total = vf.subtotal - vf.descuento;
                                        context.VentasXFuncion.Add(vf);
                                    }
                                    context.SaveChanges();
                                    //detalle de venta
                                    DetalleVenta dt = new DetalleVenta();
                                    dt.cantEntradas = paquete.cantidad;
                                    dt.codFuncion = paquete.idFuncion;
                                    dt.codPrecE = pr.codPrecioEvento;
                                    dt.total = vf.total;
                                    dt.entradasDev = 0;
                                    dt.descTot = vf.descuento;
                                    dt.codVen = vf.codVen;
                                    context.DetalleVenta.Add(dt);
                                    if (paquete.filas != null && paquete.filas.Count > 0) paquete.tieneAsientos = true;
                                    //actualizo el mondo adeudado
                                    Eventos evento = context.Eventos.Find(paquete.idEvento);
                                    evento.monto_adeudado += (double)(paquete.cantidad * pr.precio * evento.porccomision / 100 + evento.montoFijoVentaEntrada);
                                    context.SaveChanges();
                                    //si tengo asientos, actualizo los asientos a ocupado
                                    if (paquete.tieneAsientos)
                                    {
                                        for (int i = 0; i < paquete.cantidad; i++)
                                        {
                                            int col = paquete.columnas[i];
                                            int fil = paquete.filas[i];
                                            List<Asientos> listasiento = context.Asientos.Where(x => x.codZona == paquete.idZona && x.fila == fil && x.columna == col).ToList();
                                            AsientosXFuncion actAsiento = context.AsientosXFuncion.Find(listasiento.First().codAsiento, paquete.idFuncion);
                                            if (actAsiento.estado != "libre")
                                            {
                                                throw new OptimisticConcurrencyException();
                                            }
                                            actAsiento.estado = MagicHelpers.Ocupado;
                                            actAsiento.codDetalleVenta = dt.codDetalleVenta;
                                            actAsiento.PrecioPagado = pr.precio;
                                        }
                                    }
                                    else
                                    {
                                        //si no tiene asientos es una zonax funcion
                                        ZonaxFuncion ZXF = context.ZonaxFuncion.Find(paquete.idFuncion, paquete.idZona);
                                        if (ZXF.cantLibres < paquete.cantidad)
                                        {
                                            //genero una exception para detener la compra?
                                            throw new OptimisticConcurrencyException();
                                        }
                                        else
                                            ZXF.cantLibres -= paquete.cantidad;
                                    }
                                    try
                                    {
                                        CuentaUsuario dbCuenta = context.CuentaUsuario.Find(cuenta.correo);
                                        dbCuenta.puntos += context.Eventos.Find(paquete.idEvento).puntosAlCliente * paquete.cantidad;
                                    }
                                    catch (Exception ex)
                                    {
                                        //usuario anonimo
                                    }

                                }
                                context.SaveChanges();
                            }
                            catch (OptimisticConcurrencyException ex)
                            {
                                //hubo un problema con la compra, remuevo el item
                                if (idVenta != 0)
                                {
                                    context.Dispose();
                                    Ventas remover = db.Ventas.Find(idVenta);
                                    db.Ventas.Remove(remover);
                                    db.SaveChanges();
                                }
                                TempData["tipo"] = "alert alert-warning";
                                TempData["message"] = "Error en la venta.";
                                return RedirectToAction("CarritoVentas");
                            }
                        }
                        TempData["tipo"] = "alert alert-success";
                        TempData["message"] = "Venta Realizada";
                        //si toda la compra se procesa de manera correcta eliminamos los session
                        Session["CarritoItemVentas"] = null;
                        Session["CarritoVendedor"] = null;
                        //enviamos un correo al cliente que lo compro - no funcionara con un anonimo
                        EmailController.EnviarCorreoCompra(idVenta, cuenta.correo);
                        return RedirectToAction("Index2", "Home");
                    }
                }
                //saco el carrito del session
                List<CarritoItem> carrito2 = (List<CarritoItem>)Session["CarritoItemVentas"];
                //lista de bancos
                List<Banco> bancos = db.Banco.ToList();
                ViewBag.Bancos = new SelectList(bancos, "codigo", "nombre");
                //lista de tarjetas
                List<TipoTarjeta> tipoTarjeta = db.TipoTarjeta.ToList();
                ViewBag.TipoTarjeta = new SelectList(tipoTarjeta, "idTipoTar", "nombre");
                List<Promociones> listaPromociones = new List<Promociones>();
                List<Promociones> listaPromocionesEfectivo = new List<Promociones>();
                double total = 0;
                double descuento = 0;
                double? descuentoE = 0;
                foreach (CarritoItem item in carrito2)
                {
                    total += item.precio;
                    Promociones promocion = PromocionController.CalculaMejorPromocionTarjeta(item.idEvento, bancos.First().codigo, tipoTarjeta.First().idTipoTar);
                    if (promocion == null)
                    {
                        Promociones dummy = new Promociones();
                        dummy.codPromo = -1;
                        listaPromociones.Add(dummy);
                    }
                    else
                    {
                        descuento += item.precio * promocion.descuento.Value / 100;
                        listaPromociones.Add(promocion);
                    }
                    promocion = PromocionController.CalculaMejorPromocionEfectivo(item.idEvento);
                    if (promocion != null)
                    {
                        if (item.cantidad >= promocion.cantAdq)
                        {
                            descuentoE += 1.0 * promocion.cantAdq * (item.precio / item.cantidad) * (1 - (promocion.cantComp.Value * 1.0 / promocion.cantAdq.Value));
                            listaPromocionesEfectivo.Add(promocion);
                        }
                        else
                        {
                            Promociones dummy = new Promociones();
                            dummy.codPromo = -1;
                            listaPromocionesEfectivo.Add(dummy);
                        }
                    }
                    else
                    {
                        Promociones dummy = new Promociones();
                        dummy.codPromo = -1;
                        listaPromocionesEfectivo.Add(dummy);
                    }
                }
                ViewBag.PromocionesEfectivo = listaPromocionesEfectivo;
                ViewBag.Promociones = listaPromociones;
                ViewBag.Funciones = model.idFunciones;
                ViewBag.Total = total;
                //efectivo
                if (model.MontoTar == 0 && model.MontoEfe >= 0 && model.MontoDolares >= 0)
                {
                    ViewBag.DescuentoE = model.Descuento;
                    ViewBag.MontoPagarE = model.MontoPagar;
                    ViewBag.MontoSE = model.MontoEfe;
                    ViewBag.MontoDE = model.MontoDolares;
                    ViewBag.VueltoE = model.Vuelto;
                    //tarjeta
                    ViewBag.Descuento = descuento;
                    ViewBag.MontoPagarT = total - descuento;
                    ViewBag.MontoTarjeta = total - descuento;
                    //mixto
                    ViewBag.MontoPagarM = total;
                    ViewBag.MontoSM = 0;
                    ViewBag.MontoDM = 0;
                    ViewBag.MontoTarjetaM = 0;
                    ViewBag.VueltoM = 0;
                    model.modalidad = 1;
                }
                //tarjeta
                if (model.MontoTar > 0 && model.MontoEfe == 0 && model.MontoDolares == 0)
                {
                    ViewBag.DescuentoE = descuentoE;
                    ViewBag.MontoPagarE = total - descuentoE;
                    ViewBag.MontoSE = 0;
                    ViewBag.MontoDE = 0;
                    ViewBag.VueltoE = 0;
                    //tarjeta
                    ViewBag.Descuento = model.Descuento;
                    ViewBag.MontoPagarT = model.MontoPagar;
                    ViewBag.MontoTarjeta = model.MontoTar;
                    //mixto
                    ViewBag.MontoPagarM = total;
                    ViewBag.MontoSM = 0;
                    ViewBag.MontoDM = 0;
                    ViewBag.MontoTarjetaM = 0;
                    ViewBag.VueltoM = 0;
                    model.modalidad = 2;
                }

                if (model.MontoTar >= 0 && model.MontoEfe >= 0 && model.MontoDolares >= 0)
                {
                    ViewBag.DescuentoE = descuentoE;
                    ViewBag.MontoPagarE = total - descuentoE;
                    ViewBag.MontoSE = 0;
                    ViewBag.MontoDE = 0;
                    ViewBag.VueltoE = 0;
                    //tarjeta
                    ViewBag.Descuento = descuento;
                    ViewBag.MontoPagarT = total - descuento;
                    ViewBag.MontoTarjeta = total - descuento;
                    //mixto
                    ViewBag.MontoPagarM = model.MontoPagar;
                    ViewBag.MontoSM = model.MontoEfe;
                    ViewBag.MontoDM = model.MontoDolares;
                    ViewBag.MontoTarjetaM = model.MontoTar;
                    ViewBag.VueltoM = model.Vuelto;
                    model.modalidad = 3;
                }
                ViewBag.Mes = Fechas.Mes();
                ViewBag.AnVen = Fechas.Anio();
                return View(model);
            }
            TempData["tipo"] = "alert alert-warning";
            TempData["message"] = "No hay items en el carrito.";
            return RedirectToAction("CarritoVentas");
        }
        public async Task<ActionResult> ChangePassword(ChangePasswordViewModel model)
        {
            var db = new inf245netsoft();
            string correo = User.Identity.Name;
            CuentaUsuario cliente = db.CuentaUsuario.Where(c => c.correo == correo).First();

            if (cliente.contrasena == model.OldPassword)
            {
                if (cliente.contrasena != model.NewPassword)
                {
                    if (model.NewPassword == model.ConfirmPassword)
                    {
                        var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
                        if (result.Succeeded)
                        {
                            var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
                            cliente.contrasena = model.NewPassword;
                            db.SaveChanges();
                            TempData["tipo"] = "alert alert-success";
                            TempData["message"] = "Contraseña cambiada Exitosamente";
                            if (user != null)
                            {
                                await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                            }
                            /*Aca deberia retornarte a MiCuenta de CuentaUsuario*/
                            return RedirectToAction("MiCuenta", "CuentaUsuario");
                        }
                        else
                        {
                            ModelState.AddModelError("NewPassword", "Las contraseñas deben tener 6 caracteres como mínimo y una combinación de caracteres especiales, letras, letras mayúsculas y números");
                        }
                    }
                    else
                    {
                        //cuando la contraseña nueva y la confirmacion no son iguales
                        ModelState.AddModelError("ConfirmPassword", "Las contraseñas no coinciden");
                    }
                }
                else
                {
                    //contrseña actual igual a la contraseña nueva
                    ModelState.AddModelError("NewPassword", "Ingrese una contraseña diferente a la actual.");
                    /*var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
                    if (!result.Succeeded)
                    {
                        ModelState.AddModelError("NewPassword", "Las contraseñas deben tener 6 caracteres como mínimo y una combinación de caracteres especiales, letras, letras mayúsculas y números");
                    }*/
                }
            }
            else
            {
                //contreña actual diferente a la ingresa
                ModelState.AddModelError("OldPassword", "Contraseña ingresada no es correcta");
            }
            return View(model);
        }
        public ActionResult ComprarEntrada(ComprarEntradaModel model)
        {
            if (ModelState.IsValid)
            {
                if (ValidacionesCompra(model))
                {
                    int idVenta = 0;
                    DateTime hoy = DateTime.Today;
                    CuentaUsuario cuenta = new CuentaUsuario();
                    using (var context = new inf245netsoft())
                    {
                        try
                        {
                            List<CarritoItem> carrito = (List<CarritoItem>)Session["CarritoItem"];
                            Ventas ve = new Ventas();
                            int cantidadEntradasTotales = carrito.Sum(c => c.cantidad);

                            if (Session["UsuarioLogueado"] != null)
                            {
                                cuenta = (CuentaUsuario)Session["UsuarioLogueado"];
                                ve.CuentaUsuario = context.CuentaUsuario.Find(cuenta.usuario);
                                ve.cliente = cuenta.usuario;
                            }
                            else
                            {
                                ve.CuentaUsuario = context.CuentaUsuario.Find(MagicHelpers.AnonimoUniversal);
                                ve.cliente = model.Nombre;
                            }
                            ve.fecha = DateTime.Now;
                            ve.cantAsientos = cantidadEntradasTotales;
                            //de todas maneras en la venta se registra el nombre, dni y tipo de documento del que esta comprando.
                            ve.cliente = model.Nombre;
                            ve.codDoc = model.Dni;
                            //--
                            ve.Estado = MagicHelpers.Compra;
                            ve.tipoDoc = 1;
                            ve.montoCreditoSoles = model.MontoPagar;
                            ve.montoDev = 0;
                            ve.montoEfectivoDolares = 0;
                            ve.montoEfectivoSoles = 0;
                            ve.MontoTotalSoles = model.MontoPagar;
                            ve.entradasDev = 0;
                            context.Ventas.Add(ve);
                            try
                            {
                                context.SaveChanges();
                                idVenta = ve.codVen;
                            }
                            catch (DbEntityValidationException dbEx)
                            {
                                foreach (var validationErrors in dbEx.EntityValidationErrors)
                                {
                                    foreach (var validationError in validationErrors.ValidationErrors)
                                    {
                                        Trace.TraceInformation("Property: {0} Error: {1}",
                                                                validationError.PropertyName,
                                                                validationError.ErrorMessage);
                                    }
                                }
                            }
                            //para cada item del carrito
                            for (int w = 0; w < carrito.Count; w++)
                            {
                                CarritoItem paquete = carrito[w];
                                //zona del evento
                                ZonaEvento zo = context.ZonaEvento.Find(paquete.idZona);
                                //en que perdiodo de venta estamos
                                PeriodoVenta per = context.PeriodoVenta.Where(c => c.codEvento == paquete.idEvento && c.fechaInicio <= hoy && c.fechaFin >= hoy).ToList().First();
                                PrecioEvento pr = context.PrecioEvento.Where(c => c.codZonaEvento == paquete.idZona && c.codPeriodoVenta == per.idPerVent).ToList().First();
                                //la venta x funcion requerida
                                VentasXFuncion vf = new VentasXFuncion();
                                //si ya existe una venta x funcion de esta venta
                                if (context.VentasXFuncion.Any(c => c.codVen == ve.codVen && c.codFuncion == paquete.idFuncion))
                                {
                                    vf = context.VentasXFuncion.Where(c => c.codVen == ve.codVen && c.codFuncion == paquete.idFuncion).First();
                                    vf.cantEntradas += paquete.cantidad;
                                    vf.subtotal += paquete.cantidad * pr.precio;
                                    float? porcDescuento = 0;
                                    if (model.idPromociones[w] != -1)
                                    {
                                        int idPromocion = model.idPromociones[w];
                                        Promociones promocion = context.Promociones.Where(c => c.codPromo == idPromocion && c.codEvento == paquete.idEvento).First();
                                        porcDescuento = promocion.descuento / 100;
                                    }
                                    vf.descuento += (int?)(vf.subtotal * porcDescuento);
                                    vf.total += paquete.cantidad * pr.precio - vf.descuento;
                                }
                                else
                                {
                                    //creo una nueva ventaxfuncion
                                    vf.codVen = ve.codVen;
                                    vf.cantEntradas = paquete.cantidad;
                                    vf.codFuncion = paquete.idFuncion;
                                    vf.Ventas = ve;
                                    vf.Funcion = context.Funcion.Find(paquete.idFuncion);
                                    vf.hanEntregado = false;
                                    float? porcDescuento = 0;
                                    if (model.idPromociones[w] != -1)
                                    {
                                        int idPromocion = model.idPromociones[w];
                                        Promociones promocion = context.Promociones.Where(c => c.codPromo == idPromocion && c.codEvento == paquete.idEvento).First();
                                        porcDescuento = promocion.descuento / 100;
                                    }
                                    vf.subtotal = paquete.cantidad * pr.precio;
                                    vf.descuento = (int?)(vf.subtotal * porcDescuento);
                                    vf.total = vf.subtotal - vf.descuento;
                                    context.VentasXFuncion.Add(vf);
                                }
                                context.SaveChanges();
                                //detalle de venta
                                DetalleVenta dt = new DetalleVenta();
                                dt.cantEntradas = paquete.cantidad;
                                dt.codFuncion = paquete.idFuncion;
                                dt.codPrecE = pr.codPrecioEvento;

                                dt.total = vf.total;
                                dt.entradasDev = 0;
                                dt.descTot = vf.descuento;
                                dt.codVen = vf.codVen;
                                context.DetalleVenta.Add(dt);
                                if (paquete.filas != null && paquete.filas.Count > 0) paquete.tieneAsientos = true;
                                //actualizo el mondo adeudado 
                                Eventos evento = context.Eventos.Find(paquete.idEvento);
                                evento.monto_adeudado += (double)(paquete.cantidad * pr.precio * evento.porccomision / 100 + evento.montoFijoVentaEntrada);
                                context.SaveChanges();
                                //si tengo asientos, actualizo los asientos a ocupado
                                if (paquete.tieneAsientos)
                                {
                                    for (int i = 0; i < paquete.cantidad; i++)
                                    {
                                        int col = paquete.columnas[i];
                                        int fil = paquete.filas[i];
                                        List<Asientos> listasiento = context.Asientos.Where(x => x.codZona == paquete.idZona && x.fila == fil && x.columna == col).ToList();
                                        AsientosXFuncion actAsiento = context.AsientosXFuncion.Find(listasiento.First().codAsiento, paquete.idFuncion);
                                        if (actAsiento.estado != "libre")
                                        {
                                            throw new OptimisticConcurrencyException();
                                        }
                                        actAsiento.estado = MagicHelpers.Ocupado;
                                        actAsiento.codDetalleVenta = dt.codDetalleVenta;
                                        actAsiento.PrecioPagado = pr.precio;
                                    }
                                }
                                else
                                {
                                    //si no tiene asientos es una zonax funcion
                                    ZonaxFuncion ZXF = context.ZonaxFuncion.Find(paquete.idFuncion, paquete.idZona);
                                    if (ZXF.cantLibres < paquete.cantidad)
                                    {
                                        //genero una exception para detener la compra?
                                        throw new OptimisticConcurrencyException();
                                    }
                                    else
                                        ZXF.cantLibres -= paquete.cantidad;
                                }
                                if (User.Identity.IsAuthenticated)
                                {//si es u usuario registrado le aumento los puntos que tiene
                                    try
                                    {
                                        CuentaUsuario dbCuenta = context.CuentaUsuario.Find(cuenta.correo);
                                        dbCuenta.puntos += context.Eventos.Find(paquete.idEvento).puntosAlCliente * paquete.cantidad;
                                    }
                                    catch (Exception ex)
                                    {
                                        //anonimo
                                    }
                                }
                            }
                            context.SaveChanges();
                        }
                        catch (OptimisticConcurrencyException ex)
                        {
                            //hubo un problema con la compra, remuevo el item
                            if (idVenta != 0)
                            {
                                context.Dispose();
                                Ventas remover = db.Ventas.Find(idVenta);
                                db.Ventas.Remove(remover);
                                db.SaveChanges();
                            }
                            TempData["tipo"] = "alert alert-warning";
                            TempData["message"] = "Error en la compra.";
                            return RedirectToAction("MiCarrito");
                        }
                    }
                    TempData["tipo"] = "alert alert-success";
                    TempData["message"] = "Compra Realizada. Muchas Gracias.";
                    //si toda la compra se procesa de manera correcta eliminamos los session
                    Session["CarritoItem"] = null;
                    Session["Carrito"] = null;
                    if (Request.IsAuthenticated)
                    {
                        EmailController.EnviarCorreoCompra(idVenta, User.Identity.Name);
                    }
                    return RedirectToAction("Index", "Home");
                }
            }
            //saco el carrito del session
            List<CarritoItem> carrito2 = (List<CarritoItem>)Session["CarritoItem"];
            //lista de bancos
            List<Banco> bancos = db.Banco.ToList();
            ViewBag.Bancos = new SelectList(bancos, "codigo", "nombre", model.idBanco);
            //lista de tarjetas
            List<TipoTarjeta> tipoTarjeta = db.TipoTarjeta.ToList();
            ViewBag.TipoTarjeta = new SelectList(tipoTarjeta, "idTipoTar", "nombre", model.idTipoTarjeta);
            List<Promociones> listaPromociones = new List<Promociones>();
            double total = 0;
            double descuento = 0;
            foreach (CarritoItem item in carrito2)
            {
                total += item.precio;
                Promociones promocion = PromocionController.CalculaMejorPromocionTarjeta(item.idEvento, model.idBanco, model.idTipoTarjeta);
                if (promocion == null)
                {
                    Promociones dummy = new Promociones();
                    dummy.codPromo = -1;
                    listaPromociones.Add(dummy);
                }
                else
                {
                    descuento += item.precio * promocion.descuento.Value / 100;
                    listaPromociones.Add(promocion);
                }
            }
            ViewBag.Descuento = descuento;
            ViewBag.Promociones = listaPromociones;
            ViewBag.Total = total;
            ViewBag.Pagar = total - descuento;
            ViewBag.Mes = Fechas.Mes();
            ViewBag.AnVen = Fechas.Anio();
            return View(model);
        }