コード例 #1
1
ファイル: FacturaPac.cs プロジェクト: moisesiq/aupaga
        public ResAcc<string> CancelarFactura(string sUuid, string sRfc, byte[] ArchivoPfx, string sContraseniaPfx)
        {
            var Res = new ResAcc<string>();
            try
            {
                var oServicio = new Edicom.CFDiService();

                // Se manda cancelar la factura, prueba o normal
                if (this.Prueba)
                {
                    Res.Respuesta = "Resultado de prueba. No hay mecanismo de cancelación en Edicom.";
                }
                else
                {
                    CancelaResponse oCancel = oServicio.cancelaCFDi(this.Usuario, this.Contrasenia, sRfc, new string[] { sUuid }, ArchivoPfx, sContraseniaPfx);
                    Res.Respuesta = oCancel.ack;
                }
                Res.Exito = true;
            }
            catch (Exception e)
            {
                Res.Mensaje = e.Message;
            }
            return Res;
        }
コード例 #2
0
ファイル: FacturaSeguridad.cs プロジェクト: moisesiq/aupaga
        public ResAcc<string> GenerarSelloDigital(string sArchivoKey, string sContrasenia, string sCadenaOriginal)
        {
            var Res = new ResAcc<string>(true);
            try
            {
                byte[] encryptedPrivateKeyInfoData = File.ReadAllBytes(sArchivoKey);
                AsymmetricKeyParameter parameter = PrivateKeyFactory.DecryptKey(sContrasenia.ToCharArray(), encryptedPrivateKeyInfoData);
                MemoryStream stream = new MemoryStream();
                new StreamWriter(stream);
                StringWriter writer = new StringWriter();
                new PemWriter(writer).WriteObject(parameter);
                writer.Close();
                ISigner signer = SignerUtilities.GetSigner("SHA1WithRSA");
                byte[] bytes = Encoding.UTF8.GetBytes(sCadenaOriginal);
                signer.Init(true, parameter);
                signer.BlockUpdate(bytes, 0, bytes.Length);
                Res.Respuesta = Convert.ToBase64String(signer.GenerateSignature()).ToString();
            } catch (Exception e) {
                Res.Exito = false;
                Res.Mensaje = "Error al generar el sello digital\n\n";
                Res.Mensaje += (e.InnerException == null ? e.Message : e.InnerException.Message);
            }

            return Res;
        }
コード例 #3
0
ファイル: FacturaPac.cs プロジェクト: moisesiq/aupaga
        public ResAcc<string> TimbrarFactura(byte[] XmlFactura)
        {
            var Res = new ResAcc<string>();
            try
            {
                var oServicio = new Edicom.CFDiService();
                byte[] oCfdiZip;

                // Se llama el servico de Edicom, prueba o normal
                if (this.Prueba)
                    oCfdiZip = oServicio.getCfdiTest(this.Usuario, this.Contrasenia, XmlFactura);
                else
                    oCfdiZip = oServicio.getCfdi(this.Usuario, this.Contrasenia, XmlFactura);

                var oZip = new AccesoZip(oCfdiZip);
                var oCfdi = oZip.ObtenerArchivo(FacturaPac.CfdiNombre);
                Res.Respuesta = Encoding.UTF8.GetString(oCfdi);
                Res.Exito = true;
            }
            catch (Exception e)
            {
                Res.Mensaje = e.Message;
            }

            return Res;
        }
コード例 #4
0
ファイル: Consultas.cs プロジェクト: moisesiq/aupaga
        public static ResAcc ValidarPermiso(int iUsuarioID, string sPermiso)
        {
            var oUsuarioPerV = Datos.GetEntity <UsuariosPermisosView>(c => c.UsuarioID == iUsuarioID && c.Permiso == sPermiso);

            bool bValido = Datos.Exists <UsuariosPermisosView>(c => c.UsuarioID == iUsuarioID && c.Permiso == sPermiso);

            if (bValido)
            {
                return(new ResAcc(true));
            }
            else
            {
                var oRes     = new ResAcc(false);
                var oPermiso = Datos.GetEntity <Permiso>(c => c.NombrePermiso == sPermiso && c.Estatus);
                if (oPermiso == null)
                {
                    oRes.Mensaje = "El Permiso especificado ni siquiera existe. ¡Échame la mano!";
                }
                else
                {
                    oRes.Mensaje = oPermiso.MensajeDeError;
                }
                return(oRes);
            }
        }
コード例 #5
0
ファイル: Consultas.cs プロジェクト: moisesiq/aupaga
        public static ResAcc ValidarPermiso(int iUsuarioID, string sPermiso)
        {
            var oUsuarioPerV = Datos.GetEntity<UsuariosPermisosView>(c => c.UsuarioID == iUsuarioID && c.Permiso == sPermiso);

            bool bValido = Datos.Exists<UsuariosPermisosView>(c => c.UsuarioID == iUsuarioID && c.Permiso == sPermiso);
            if (bValido)
            {
                return new ResAcc(true);
            }
            else
            {
                var oRes = new ResAcc(false);
                var oPermiso = Datos.GetEntity<Permiso>(c => c.NombrePermiso == sPermiso && c.Estatus);
                if (oPermiso == null)
                    oRes.Mensaje = "El Permiso especificado ni siquiera existe. ¡Échame la mano!";
                else
                    oRes.Mensaje = oPermiso.MensajeDeError;
                return oRes;
            }
        }
コード例 #6
0
ファイル: UtilLocal.cs プロジェクト: moisesiq/aupaga
        public static ResAcc <Usuario> ValidarObtenerUsuario(List <string> oPermisos, bool bCumplirTodosLosPermisos, string sTitulo)
        {
            var Res = new ResAcc <Usuario>(false);

            var frmValidar = new ValidarUsuario(oPermisos, bCumplirTodosLosPermisos);

            if (sTitulo != null)
            {
                frmValidar.Text = sTitulo;
            }

            if (frmValidar.ShowDialog(Principal.Instance) == DialogResult.OK)
            {
                Res.Respuesta = frmValidar.UsuarioSel;
                Res.Exito     = true;
            }
            Res.Codigo = (int)frmValidar.DialogResult;
            frmValidar.Dispose();

            return(Res);
        }
コード例 #7
0
ファイル: Ventas.cs プロジェクト: moisesiq/aupaga
        public static ResAcc<int> GenerarFacturaCancelacion(int iFacturaID, List<int> oIdsDevoluciones)
        {
            // Se obtiene el folio fiscal
            var oFactura = Datos.GetEntity<VentaFactura>(c => c.VentaFacturaID == iFacturaID && c.Estatus);
            string sFolioFiscal = oFactura.FolioFiscal;

            // Se generan los datos de la cancelación
            DateTime dAhora = DateTime.Now;
            var oFacturaDevolucion = new VentaFacturaDevolucion()
            {
                VentaFacturaID = iFacturaID,
                Fecha = dAhora,
                EsCancelacion = true
            };
            // Se genera el detalle de la devolución de factura, con los Ids de las devoluciones incluidas
            var oFacturaDevDet = new List<VentaFacturaDevolucionDetalle>();
            foreach (int iDevolucionID in oIdsDevoluciones)
                oFacturaDevDet.Add(new VentaFacturaDevolucionDetalle() { VentaDevolucionID = iDevolucionID });
            Guardar.FacturaDevolucion(oFacturaDevolucion, oFacturaDevDet);

            // Se manda cancelar la factura, y completar los procesos correspondientes
            var ResCanc = VentasLoc.GenerarFacturaCancelacion(sFolioFiscal, oFacturaDevolucion.VentaFacturaDevolucionID);

            /* Ya no se sale, pues aunque haya error, se deben guardar los datos, ya que la venta sí se canceló
            if (ResC.Error)
                return new ResAcc<bool>(false, ResC.Mensaje);
            */

            var Res = new ResAcc<int>(ResCanc.Exito, ResCanc.Mensaje);
            Res.Respuesta = oFacturaDevolucion.VentaFacturaDevolucionID;

            return Res;
        }
コード例 #8
0
ファイル: Ventas.cs プロジェクト: moisesiq/aupaga
        public static ResAcc<int> GenerarNotaDeCreditoFiscal(List<ProductoVenta> oDetalle, int iClienteID, int iUsuarioID)
        {
            // Se crea la instancia de la clase de Facturación Electrónica
            var oFacturaE = new FacturaElectronica();
            var oConfig = TheosProc.Config.ValoresVarios("Facturacion.");
            // Se llenan los valores de configuración y los datos del emisor
            VentasLoc.FeLlenarDatosComunes(ref oFacturaE, oConfig);

            // Se llenan los datos generales de la factura
            DateTime dAhora = DateTime.Now;

            // Se obtiene el nombre del vendedor
            var oUsuario = Datos.GetEntity<Usuario>(q => q.UsuarioID == iUsuarioID && q.Estatus);
            string sVendedores = oUsuario.NombrePersona;
            oFacturaE.Adicionales = new Dictionary<string, string>();
            oFacturaE.Adicionales.Add("Vendedor", sVendedores);

            oFacturaE.Fecha = dAhora;
            oFacturaE.FormaDePago = "Una sola exhibición";
            oFacturaE.LugarDeExpedicion = string.Format("{0}, {1}", oConfig["Facturacion.Municipio"], oConfig["Facturacion.Estado"]);
            oFacturaE.TipoDeComprobante = Enumerados.TiposDeComprobante.Egreso;
            oFacturaE.TasaDeImpuesto = GlobalClass.ConfiguracionGlobal.IVA.ToString();
            oFacturaE.MetodoDePago = CatFe.MetodosDePago.Otros;

            // Se llenan los datos del receptor
            var ResRec = VentasLoc.FeLlenarDatosReceptor(ref oFacturaE, iClienteID);
            if (ResRec.Error)
                return new ResAcc<int>(false, ResRec.Mensaje);

            // Se agregan datos adicionales
            oFacturaE.Adicionales.Add("FacturaOrigen", "");

            // Se llenan los conceptos de la factura
            decimal mSubtotal = 0, mIva = 0;
            oFacturaE.Conceptos = new List<Concepto>();
            foreach (var oDet in oDetalle)
            {
                oFacturaE.Conceptos.Add(new Concepto()
                {
                    Identificador = oDet.NumeroDeParte,
                    Cantidad = oDet.Cantidad,
                    Unidad = oDet.UnidadDeMedida,
                    Descripcion = oDet.NombreDeParte,
                    ValorUnitario = oDet.PrecioUnitario,
                    Iva = oDet.Iva
                });
                mSubtotal += oDet.PrecioUnitario;
                mIva += oDet.Iva;
            }

            // Se comienza a procesar la facturación electrónica

            // Se envía la factura y se obtiene el Xml generado
            var ResXml = VentasLoc.FeEnviarFactura(ref oFacturaE);
            bool bFacturada = ResXml.Exito;
            /* if (ResXml.Error)
                return new ResAcc<int>(false, ResXml.Mensaje);
            */
            string sCfdiTimbrado = ResXml.Respuesta;

            // Se guarda la información
            var oFolioFactura = VentasLoc.GenerarFolioDeFacturaDevolucion();
            oFacturaE.Serie = oFolioFactura["Serie"];
            oFacturaE.Folio = oFolioFactura["Folio"];
            var oNota = new NotaDeCreditoFiscal()
            {
                Fecha = dAhora,
                ClienteID = iClienteID,
                SucursalID = GlobalClass.SucursalID,
                FolioFiscal = (oFacturaE.Timbre == null ? "" : oFacturaE.Timbre.FolioFiscal),
                Serie = oFacturaE.Serie,
                Folio = oFacturaE.Folio,
                Subtotal = mSubtotal,
                Iva = mIva,
                RealizoUsuarioID = iUsuarioID
            };
            Datos.Guardar<NotaDeCreditoFiscal>(oNota);
            // Se guarda el detalle de la Nota de Crédito
            foreach (var oReg in oDetalle)
            {
                int iVentaID = Util.Entero(oReg.NumeroDeParte);
                if (iVentaID <= 0) continue;
                Datos.Guardar<NotaDeCreditoFiscalDetalle>(new NotaDeCreditoFiscalDetalle()
                {
                    NotaDeCreditoFiscalID = oNota.NotaDeCreditoFiscalID,
                    VentaID = iVentaID,
                    Descuento = oReg.PrecioUnitario,
                    IvaDescuento = oReg.Iva
                });
            }

            // Se manda guardar la factura, en pdf y xml
            if (bFacturada)
                VentasLoc.FeGuardarArchivosFacturaDevolucion(ref oFacturaE, sCfdiTimbrado, (oFacturaE.Serie + oFacturaE.Folio));

            // Se manda la nota de crédito generada, por correo
            // VentasProc.EnviarFacturaDevolucionPorCorreo(oFacturaDevolucion.VentaFacturaDevolucionID);

            // Se manda imprimir la factura
            // ..

            var oRes = new ResAcc<int>(bFacturada, oNota.NotaDeCreditoFiscalID);
            if (!bFacturada)
                oRes.Mensaje = ResXml.Mensaje;
            return oRes;
        }
コード例 #9
0
ファイル: Ventas.cs プロジェクト: moisesiq/aupaga
        private static ResAcc<string> FeEnviarFactura(ref FacturaElectronica oFacturaE)
        {
            // Se genera el Xml inicial, con el formato que pide el Sat
            var ResXml = oFacturaE.GenerarFactura(true);
            if (ResXml.Error)
                return new ResAcc<string>(false, ResXml.Mensaje);
            string sCfdi = ResXml.Respuesta;

            // Se manda a timbrar el Xml con el proveedor Pac
            ResXml = oFacturaE.TimbrarFactura(sCfdi, !GlobalClass.Produccion);
            if (ResXml.Error)
                return new ResAcc<string>(false, ResXml.Mensaje);
            string sCfdiTimbrado = ResXml.Respuesta;

            var Res = new ResAcc<string>(true);
            Res.Respuesta = sCfdiTimbrado;
            return Res;
        }
コード例 #10
0
ファイル: FacturaElectronica.cs プロジェクト: moisesiq/aupaga
        public ResAcc<string> GenerarFactura()
        {
            // Se genera el Xml
            var ResXml = FacturaXml.GenerarXml(this);
            if (ResXml.Error)
                return new ResAcc<string>(false, ResXml.Mensaje);
            // Se llenan algunos datos generados
            /* this.NumeroDeCertificado = ResXml.Respuesta.NumeroDeCertificado;
            this.Certificado = ResXml.Respuesta.Certificado;
            this.Sello = ResXml.Respuesta.Sello;
            this.XmlFactura = ResXml.Respuesta.XmlFactura;
            */

            var Res = new ResAcc<string>(true);
            Res.Respuesta = this.XmlFactura;
            return Res;
        }
コード例 #11
0
ファイル: FacturaXml.cs プロジェクト: moisesiq/aupaga
        public static ResAcc<TimbreXml> LeerXmlTimbrado(string sXmlFactura)
        {
            var Res = new ResAcc<TimbreXml>();

            XmlDocument oXml = new XmlDocument();
            oXml.LoadXml(sXmlFactura);
            var oTfds = oXml.GetElementsByTagName("tfd:TimbreFiscalDigital");
            if (oTfds.Count <= 0)
            {
                Res.Mensaje = "El Xml no contiene la información de timbrado.";
                return Res;
            }
            try
            {
                var oTimbreXml = new TimbreXml();
                var oTfd = oTfds[0];
                oTimbreXml.FolioFiscal = oTfd.Attributes["UUID"].Value;
                oTimbreXml.SelloSat = oTfd.Attributes["selloSAT"].Value;
                oTimbreXml.CertificadoSat = oTfd.Attributes["noCertificadoSAT"].Value;
                oTimbreXml.FechaCertificacion = Convert.ToDateTime(oTfd.Attributes["FechaTimbrado"].Value);

                // Se genera la cadena original del timbre fiscal
                var oFacturaComps = oXml.GetElementsByTagName("cfdi:Comprobante");
                if (oFacturaComps.Count <= 0) {
                    Res.Mensaje = "El Xml no contiene la información del comprobante o está mal formado.";
                    return Res;
                }
                var oFacturaComp = oFacturaComps[0];
                string sVersion = oFacturaComp.Attributes["version"].Value;
                string sSelloFactura = oFacturaComp.Attributes["sello"].Value;
                oTimbreXml.CadenaOriginal = FacturaXml.GenerarCadenaOriginalTimbre(sVersion, sSelloFactura, oTimbreXml);

                Res.Respuesta = oTimbreXml;
            }
            catch (Exception e)
            {
                Res.Mensaje = e.Message;
                return Res;
            }

            Res.Exito = true;
            return Res;
        }
コード例 #12
0
ファイル: FacturaXml.cs プロジェクト: moisesiq/aupaga
        public static ResAcc<string> ValidarXml(string sCadenaXml, string sCadenaXsd)
        {
            var Res = new ResAcc<string>();// { Mensaje = "" };

            var EsquemaXsd = XmlSchema.Read(new StringReader(sCadenaXsd), null);
            XmlReaderSettings Config = new XmlReaderSettings();
            Config.Schemas.Add(EsquemaXsd);
            Config.ValidationType = ValidationType.Schema;
            Config.ValidationEventHandler += new ValidationEventHandler((o, e) =>
            {
                if (e.Severity == XmlSeverityType.Warning)
                {
                    Res.Mensaje += ("Warning: " + e.Message + "\n");
                }
                else if (e.Severity == XmlSeverityType.Error)
                {
                    Res.Mensaje += ("Error: " + e.Message + "\n");
                }
            });

            XmlReader LectorXml = XmlReader.Create(new StringReader(sCadenaXml), Config);

            FacturaXml.ResultadoValidacion = "";
            while (LectorXml.Read()) { }

            Res.Exito = (Res.Mensaje == null);

            return Res;
        }
コード例 #13
0
ファイル: FacturaXml.cs プロジェクト: moisesiq/aupaga
        public static ResAcc<string> TransformarXml(string sXml, string sXsl)
        {
            var Res = new ResAcc<string>(true);

            var oTexto = new StringWriterMod(Encoding.UTF8);
            var oXml = XmlWriter.Create(oTexto, FacturaXml.ConfigXml);
            XmlReader oXsl = XmlReader.Create(new StringReader(sXsl));
            XmlReader oFactura = XmlReader.Create(new StringReader(sXml));
            XslCompiledTransform TransXsl = new XslCompiledTransform();
            string sXmlRes = "";
            try
            {
                TransXsl.Load(oXsl);
                TransXsl.Transform(oFactura, oXml);
                sXmlRes = oTexto.ToString();
            }
            catch (Exception e)
            {
                Res.Exito = false;
                Res.Mensaje = "Error en transformación de Xml\n\n";
                Res.Mensaje += (e.InnerException == null ? e.Message : e.InnerException.Message);
            }
            oXsl.Close();
            oFactura.Close();
            oXml.Close();
            oTexto.Close();

            Res.Respuesta = sXmlRes;
            return Res;
        }
コード例 #14
0
ファイル: VentasDevolucion.cs プロジェクト: moisesiq/aupaga
        private void GuardarDevolucion(VentaDevolucion oDevolucion, List <VentaDevolucionDetalle> oDetalle, int?iValeClienteID)
        {
            // Se obtiene el importe total de la venta antes de la devolución
            var oVentaV = Datos.GetEntity <VentasView>(c => c.VentaID == oDevolucion.VentaID);
            // decimal mTotalAntes = oVentaV.Total;

            // Se calcula el total de lo devuelto
            decimal mImporteDev = 0;

            foreach (var oParte in oDetalle)
            {
                mImporteDev += ((oParte.PrecioUnitario + oParte.Iva) * oParte.Cantidad);
            }
            // Se guarda la devolución
            Guardar.VentaDevolucion(oDevolucion, oDetalle);

            // Se verifica cuánto se ha pagado de la venta, por si fue a crédito
            if (oVentaV.Pagado < mImporteDev)
            {
                mImporteDev = oVentaV.Pagado;
            }

            // Se genera nota de crédito o devolución de efectivo, u otro, según aplique
            int iVentaID = oDevolucion.VentaID;

            if (mImporteDev > 0)
            {
                ResAcc <int> oResPagoNeg = null;
                switch (this.ctlBusqueda.FormaDeDevolucion)
                {
                case Cat.FormasDePago.Efectivo:
                    oResPagoNeg = VentasProc.GenerarDevolucionDeEfectivo(iVentaID, mImporteDev);
                    break;

                case Cat.FormasDePago.Vale:
                    // var oVenta = General.GetEntity<Venta>(q => q.Estatus && q.VentaID == iVentaID);
                    var oResVale = VentasProc.GenerarNotaDeCredito(iValeClienteID.Value, mImporteDev, "", Cat.OrigenesNotaDeCredito.Devolucion
                                                                   , oDevolucion.VentaDevolucionID);
                    // Se genera el pago negativo por la nota de crédito generada
                    oResPagoNeg = VentasProc.GenerarPagoNegativoPorNotaDeCredito(iVentaID, mImporteDev, oResVale.Respuesta);
                    break;

                case Cat.FormasDePago.Cheque:
                case Cat.FormasDePago.Tarjeta:
                case Cat.FormasDePago.TarjetaDeDebito:
                case Cat.FormasDePago.Transferencia:
                    int iFormaDePagoID = this.ctlBusqueda.FormaDeDevolucion;
                    var oVentaPago     = Datos.GetEntity <VentaPago>(q => q.VentaID == iVentaID && q.Estatus);
                    var oFormaPago     = Datos.GetEntity <VentaPagoDetalle>(q => q.VentaPagoID == oVentaPago.VentaPagoID &&
                                                                            q.TipoFormaPagoID == iFormaDePagoID && q.Estatus);
                    // Se genera un pago negativo con la misma forma del pago a contrarestar
                    oResPagoNeg = VentasProc.GenerarPago(iVentaID, (oFormaPago.Importe * -1), iFormaDePagoID, oFormaPago.BancoID.Valor(), oFormaPago.Folio, oFormaPago.Cuenta);
                    break;
                }

                // Se guarda el dato del pago negativo correspondiente a la devolución, si aplica
                if (oResPagoNeg != null)
                {
                    // Se obtiene el primer registro de VentaPagoDetalle, y ese es el que se relaciona con la devolución, pues se supone que siempre habrá sólo uno
                    var oPagoDet = Datos.GetEntity <VentaPagoDetalle>(c => c.VentaPagoID == oResPagoNeg.Respuesta && c.Estatus);
                    oDevolucion.VentaPagoDetalleID = oPagoDet.VentaPagoDetalleID;
                    Datos.Guardar <VentaDevolucion>(oDevolucion);
                }
            }

            // Se revisa si la venta pertenece a un 9500, para realizar operaciones especiales
            var o9500 = Datos.GetEntity <Cotizacion9500>(c => c.VentaID == iVentaID && c.Estatus);

            // Si es 9500, se cambia el estatus del 9500
            if (o9500 != null)
            {
                o9500.EstatusGenericoID = Cat.EstatusGenericos.CanceladoDespuesDeVendido;
                Datos.Guardar <Cotizacion9500>(o9500);
            }

            // Se verifica si la venta generó un movimiento bancario, para borrarlo si éste no ha sido asignado
            if (oDevolucion.EsCancelacion)
            {
                var oPagoDetV = Datos.GetListOf <VentasPagosDetalleView>(c => c.VentaID == iVentaID);
                foreach (var oReg in oPagoDetV)
                {
                    if (oReg.FormaDePagoID == Cat.FormasDePago.Cheque || oReg.FormaDePagoID == Cat.FormasDePago.Tarjeta || oReg.FormaDePagoID == Cat.FormasDePago.Transferencia)
                    {
                        var oMov = Datos.GetEntity <BancoCuentaMovimiento>(c => c.RelacionTabla == Cat.Tablas.VentaPagoDetalle && c.RelacionID == oReg.VentaPagoDetalleID);
                        if (oMov != null && !oMov.FechaAsignado.HasValue)
                        {
                            Datos.Eliminar <BancoCuentaMovimiento>(oMov);
                        }
                    }
                }
            }
        }
コード例 #15
0
        private void CompletarAccionGarantia(int iGarantiaID, int?iValeClienteID)
        {
            var oGarantiaV = Datos.GetEntity <VentasGarantiasView>(c => c.VentaGarantiaID == iGarantiaID);
            var oVentaV    = Datos.GetEntity <VentasView>(c => c.VentaID == oGarantiaV.VentaID);
            int iVentaID   = oVentaV.VentaID;

            // Se cambia el estatus de la venta, cuando aplique (cuando ya no hay partes en el detalle de la venta)
            if (!Datos.Exists <VentaDetalle>(c => c.VentaID == iVentaID && c.Estatus))
            {
                var oVenta = Datos.GetEntity <Venta>(c => c.VentaID == iVentaID && c.Estatus);
                oVenta.VentaEstatusID = Cat.VentasEstatus.AGarantia;
                Datos.Guardar <Venta>(oVenta);
            }

            // Se obtiene el importe a devolver, por si fue a crédito y no se ha pagado toda la venta
            decimal mImporteDev = (oVentaV.Pagado > oGarantiaV.Total ? oGarantiaV.Total.Valor() : oVentaV.Pagado);

            // Se genera nota de crédito o devolución de efectivo, u otro, según aplique
            if (mImporteDev > 0)
            {
                ResAcc <int> oResPagoNeg = null;
                switch (oGarantiaV.AccionID)
                {
                case Cat.VentasGarantiasAcciones.ArticuloNuevo:
                case Cat.VentasGarantiasAcciones.NotaDeCredito:
                    // var oVenta = General.GetEntity<Venta>(q => q.Estatus && q.VentaID == iVentaID);
                    var oResVale = VentasProc.GenerarNotaDeCredito(iValeClienteID.Value, mImporteDev, "", Cat.OrigenesNotaDeCredito.Garantia
                                                                   , oGarantiaV.VentaGarantiaID);
                    // Se genera el pago negativo por la nota de crédito generada
                    oResPagoNeg = VentasProc.GenerarPagoNegativoPorNotaDeCredito(iVentaID, mImporteDev, oResVale.Respuesta);
                    break;

                case Cat.VentasGarantiasAcciones.Efectivo:
                    oResPagoNeg = VentasProc.GenerarDevolucionDeEfectivo(iVentaID, mImporteDev);
                    break;

                case Cat.VentasGarantiasAcciones.Cheque:
                case Cat.VentasGarantiasAcciones.Tarjeta:
                case Cat.VentasGarantiasAcciones.TarjetaDeDebito:
                case Cat.VentasGarantiasAcciones.Transferencia:
                    int iFormaDePagoID = UtilDatos.FormaDePagoDeAccionGarantia(oGarantiaV.AccionID);
                    var oVentaPago     = Datos.GetEntity <VentaPago>(q => q.VentaID == iVentaID && q.Estatus);
                    var oFormaPago     = Datos.GetEntity <VentaPagoDetalle>(q =>
                                                                            q.VentaPagoID == oVentaPago.VentaPagoID && q.TipoFormaPagoID == iFormaDePagoID && q.Estatus);
                    // Se genera un pago negativo con la misma forma del pago a contrarestar
                    oResPagoNeg = VentasProc.GenerarPago(iVentaID, (oFormaPago.Importe * -1), iFormaDePagoID, oFormaPago.BancoID.Valor(), oFormaPago.Folio, oFormaPago.Cuenta);
                    break;
                }

                // Se guarda el dato del pago negativo correspondiente a la devolución, si aplica
                if (oResPagoNeg != null)
                {
                    var oGarantia = Datos.GetEntity <VentaGarantia>(c => c.VentaGarantiaID == iGarantiaID && c.Estatus);
                    // Se obtiene el primer registro de VentaPagoDetalle, y ese es el que se relaciona con la garantía, pues se supone que siempre habrá sólo uno
                    var oPagoDet = Datos.GetEntity <VentaPagoDetalle>(c => c.VentaPagoID == oResPagoNeg.Respuesta && c.Estatus);
                    oGarantia.VentaPagoDetalleID = oPagoDet.VentaPagoDetalleID;
                    Datos.Guardar <VentaGarantia>(oGarantia);
                }
            }

            // Se verifica si es factura, en cuyo caso, se genera nota de crédito, según aplique
            if (oVentaV.Facturada)
            {
                var ResFactura = VentasLoc.GenerarFacturaDevolucionPorGarantia(iGarantiaID);
                if (ResFactura.Error)
                {
                    UtilLocal.MensajeAdvertencia("Hubo un error al generar la factura de la devolución.\n\n" + ResFactura.Mensaje);
                }
            }

            // Se crea la póliza contable correspondiente, según el caso (AfeConta)
            if (oVentaV.Facturada)
            {
                if (oVentaV.ACredito)
                {
                    if (oGarantiaV.AccionID == Cat.VentasGarantiasAcciones.ArticuloNuevo || oGarantiaV.AccionID == Cat.VentasGarantiasAcciones.NotaDeCredito)
                    {
                        ContaProc.CrearPolizaAfectacion(Cat.ContaAfectaciones.GarantiaVentaCreditoFacturaVale, oGarantiaV.VentaGarantiaID
                                                        , oGarantiaV.FolioDeVenta, oGarantiaV.MotivoObservacion);
                    }
                    else
                    {
                        ContaProc.CrearPolizaAfectacion(Cat.ContaAfectaciones.GarantiaVentaCreditoFacturadaPago, oGarantiaV.VentaGarantiaID
                                                        , oGarantiaV.FolioDeVenta, oGarantiaV.MotivoObservacion);
                    }
                }
                else
                {
                    if (oGarantiaV.AccionID == Cat.VentasGarantiasAcciones.ArticuloNuevo || oGarantiaV.AccionID == Cat.VentasGarantiasAcciones.NotaDeCredito)
                    {
                        ContaProc.CrearPolizaAfectacion(Cat.ContaAfectaciones.GarantiaVentaValeFactura, oGarantiaV.VentaGarantiaID
                                                        , oGarantiaV.FolioDeVenta, oGarantiaV.MotivoObservacion);
                    }
                    else
                    {
                        ContaProc.CrearPolizaAfectacion(Cat.ContaAfectaciones.GarantiaVentaPagoFactura, oGarantiaV.VentaGarantiaID
                                                        , oGarantiaV.FolioDeVenta, oGarantiaV.MotivoObservacion);
                    }
                }
            }
            else
            {
                if (oGarantiaV.AccionID == Cat.VentasGarantiasAcciones.ArticuloNuevo || oGarantiaV.AccionID == Cat.VentasGarantiasAcciones.NotaDeCredito)
                {
                    ContaProc.CrearPolizaAfectacion(Cat.ContaAfectaciones.GarantiaVentaValeTicket, oGarantiaV.VentaGarantiaID
                                                    , oGarantiaV.FolioDeVenta, oGarantiaV.MotivoObservacion);
                }

                // Si es tiecket a crédito, se hace ajuste temporal de pólizas
                if (oVentaV.ACredito)
                {
                    ContaProc.BorrarPolizaTemporalTicketCredito(iVentaID);
                    // Se actualizan los datos de la venta
                    oVentaV = Datos.GetEntity <VentasView>(c => c.VentaID == iVentaID);
                    ContaProc.CrearPolizaTemporalTicketCredito(iVentaID, (oVentaV.Total - oVentaV.Pagado));
                }
            }
        }