<%@ WebHandler Language="VB" Class="SIGFacturacion" %> Imports System Imports System.Web Imports System.Net.Http Imports System.Web.Http Imports System.Data Imports Newtonsoft.Json Imports Newtonsoft.Json.Linq Imports Extensiones Imports System.IO Imports Modelos Public Class SIGFacturacion : Implements IHttpHandler, IRequiresSessionState Private Property CveEmpresaFacturar As Integer = 194 Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest context.Response.ContentType = "text/plain" Dim Retorno As Boolean = False Try Dim Metodo = If(context.Request("Metodo") = Nothing, "", context.Request("Metodo").ToString()) GuardaLogFacturacion(" -------------------------- Inicio de Petición Metodo:" & Metodo & " --------------------------") If Metodo = "FactMasivaRemisiones" Then Dim pFechaI As String = "" Dim pFechaF As String = "" If context.Request("FechaI") IsNot Nothing AndAlso context.Request("FechaF") IsNot Nothing Then pFechaI = context.Request("FechaI") pFechaF = context.Request("FechaF") End If Retorno = IniciaFacturacionMasiva(CveEmpresaFacturar.ToString, pFechaI, pFechaF) End If GuardaLogFacturacion(" -------------------------- Fin de Petición Metodo:" & Metodo & " --------------------------") Catch ex As Exception ex.GuardaLog(ex.Message) End Try If Retorno Then context.Response.Write("True") Else context.Response.Write("False") End If End Sub Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property Private Function IniciaFacturacionMasiva(pCveEmpresa As String, pFechaI As String, pFechaF As String) As Boolean Dim Retorno As Boolean = True Dim JsonRetorno As New JObject() Dim CveEmpresa As Integer = pCveEmpresa.ToEntero() GuardaLogFacturacion("- Inicio de facturación ") If CveEmpresa > 0 Then GuardaLogFacturacion($"1.10 - CveE:{CveEmpresa}") Dim Usuario = ValidaUsuarioSistema(CveEmpresa) Dim FechaI, FechaF As DateTime 'EnviarCorreoFactura(New Modelos.Factura(Usuario, 844966, 1, context.ModExtensiones.DirectorioBaseEmpresas), Usuario) If String.IsNullOrEmpty(pFechaI) AndAlso String.IsNullOrEmpty(pFechaF) Then GuardaLogFacturacion("1.200") Dim FechaReferencia As Date = ClsPaginas.NowADS() If FechaReferencia.DayOfWeek = DayOfWeek.Sunday Then Dim Sabado = FechaReferencia.AddDays(-1) Dim DomingoAnterior = FechaReferencia.AddDays(-7) FechaI = New DateTime(DomingoAnterior.Year, DomingoAnterior.Month, DomingoAnterior.Day, 0, 0, 0) FechaF = New DateTime(Sabado.Year, Sabado.Month, Sabado.Day, 23, 59, 59) JsonRetorno = EjecutarFacturacionMasiva(Usuario, FechaI, FechaF, Usuario.Empresa.FacturaProduccion) Else Retorno = False GuardaLogFacturacion("Ejecución no permitida, no es el dia permitido para ejecucion o no se espeficaron las fechas") End If Else GuardaLogFacturacion("1.300") FechaI = pFechaI.ToDateTime() FechaF = pFechaF.ToDateTime() JsonRetorno = EjecutarFacturacionMasiva(Usuario, FechaI, FechaF, Usuario.Empresa.FacturaProduccion) End If End If GuardaLogFacturacion("Ejecución Exitosa, se generaron las siguientes facturas:") GuardaLogFacturacion(JsonRetorno.ToString()) Return Retorno End Function Public Shared Function GetNextWeekday(ByVal start As DateTime, ByVal day As DayOfWeek, hora As TimeSpan) As DateTime Dim daysToAdd As Integer = (CInt(day) - CInt(start.DayOfWeek) + 7) Mod 7 Dim fecha = start.AddDays(daysToAdd) Return (fecha.Date + hora) End Function Public Shared Function GetLastWeekday(ByVal start As DateTime, ByVal day As DayOfWeek, hora As TimeSpan) As DateTime Dim daysToAdd As Integer = (CInt(day) - CInt(start.DayOfWeek) - 7) Mod 7 Dim fecha = start.AddDays(daysToAdd) Return (fecha.Date + hora) End Function Private Function EjecutarFacturacionMasiva(UsuarioActual As Usuario, FechaI As DateTime, FechaF As DateTime, Optional Produccion As Boolean = True) As JObject Dim Facturas As New JArray() Dim DebeTimbrar As Boolean = True Dim Json As New JObject( New JProperty("Empresa", UsuarioActual.Empresa.Empresa), New JProperty("Usuario", UsuarioActual.Usuario), New JProperty("FechaI", FechaI.ToString("dd/MM/yyy HH:mm:ss")), New JProperty("FechaF", FechaF.ToString("dd/MM/yyy HH:mm:ss")) ) Dim DTClientes As DataTable = Nothing Dim DTRemisionesPS As DataTable = Nothing Dim ObjCliente As New ClsClientes If ObjCliente.GetClientes(-1, "-1", "-1", "-1", "-1", "-1", "-1", -1, UsuarioActual.CveEmpresa, TipoCliente:=-1) Then If ObjCliente.DtResultados.Rows.Count > 0 Then DTClientes = ObjCliente.DtResultados.Copy() End If End If ObjCliente.Dispose() If DTClientes IsNot Nothing Then 'QUITAR CLIENTES QUE NO DEBEN DE ESTAR DTClientes = DTClientes.FiltraParametros("CveCliente NOT IN (1285420,1285423,1285424) ") For Each RowCliente As DataRow In DTClientes.Rows Dim CveCliente As Integer = RowCliente("CveCliente").ToString().ToEntero() Dim DatosRemisiones As JObject = CargaRemisiones(FechaI, FechaF, CveCliente) Dim CveRemisiones As String = DatosRemisiones("VentasConcatenadas").ToString() If Not String.IsNullOrEmpty(CveRemisiones) Then Dim ObjClientes As New ClsClientes If ObjClientes.GetVentasRemisionesTotales(CveCliente, CveRemisiones, 1, UsuarioActual.CveEmpresa) Then DTRemisionesPS = ObjClientes.DtResultados.Copy() End If ObjClientes.Dispose() If DTRemisionesPS IsNot Nothing AndAlso DTRemisionesPS.Rows.Count > 0 Then Dim Resp As New Modelos.Factura.MMensajeFactura Dim CveSubProyectoMatriz As Integer = ClsPaginas.GlobalDTSubProyectos(UsuarioActual.CveEmpresa).FiltroPrimeroValor("CveSubProyecto", "TipoSucursal = 1").ToEntero() Dim ObjFactura = CreaFactura(Resp, UsuarioActual, DTRemisionesPS, RowCliente("CveCliente").ToString().ToEntero(), CveSubProyectoMatriz, 1, DatosRemisiones, FechaI, FechaF) If ObjFactura IsNot Nothing Then Resp = ObjFactura.EmitirFactura(DebeTimbrar) End If If Resp.CveVenta > 0 AndAlso Not Resp.TieneError Then If Resp.SeTimbro OrElse Not Produccion Then EnviarCorreo(ObjFactura, UsuarioActual) End If End If Facturas.Add(JObject.Parse(JsonConvert.SerializeObject(Resp))) DTRemisionesPS.Dispose() 'ObjFactura.Dispose() End If End If DTRemisionesPS = Nothing Next DTClientes.Dispose() End If Json.Add(New JProperty("Facturas", Facturas)) Return Json End Function Private Function CargaRemisiones(FechaI As DateTime, FechaF As DateTime, CveCliente As Integer) As JObject Dim json As New JObject() Dim VentasArray As New JArray Dim DTRemisiones As DataTable = Nothing Dim ObjVentas As New ClsVentas If ObjVentas.GetRemisionesSinFacturar(FechaI.ToShortDateString, FechaF.ToShortDateString, CveCliente, -1, 1, -1) Then DTRemisiones = ObjVentas.DtResultados.FiltraParametros("CveContrato = 0") End If ObjVentas.Dispose() Dim sbRemisiones As New StringBuilder Dim MensajeRemisiones As New StringBuilder Dim ObsOC As New StringBuilder Dim ObsPedido As New StringBuilder Dim ObsInv As New StringBuilder If DTRemisiones IsNot Nothing AndAlso DTRemisiones.Rows.Count > 0 Then MensajeRemisiones.Append("Remisiones: ") For Each Dr As DataRow In DTRemisiones.Rows VentasArray.Add(New JObject(New JProperty("CveVenta", Dr("CveVenta").ToString))) sbRemisiones.AppendFormat("{0},", Dr("CveVenta").ToString) MensajeRemisiones.AppendFormat("{0} {1}, ", Dr("Folio"), If(Dr("ObsFact").ToString.Length > 0, String.Format("({0})", Dr("ObsFact")), "")) ObsOC.AppendFormat("{0}, ", Dr("ObsOC")) ObsPedido.AppendFormat("{0}, ", Dr("ObsPedido")) ObsInv.AppendFormat("{0}, ", Dr("ObsInv")) Next sbRemisiones.Remove(sbRemisiones.Length - 1, 1) DTRemisiones.Dispose() End If DTRemisiones = Nothing json.Add(New JProperty("Ventas", VentasArray)) json.Add(New JProperty("VentasConcatenadas", sbRemisiones.ToString())) json.Add(New JProperty("Observaciones", MensajeRemisiones.ToString())) json.Add(New JProperty("OrdenCompra", ObsOC.ToString())) json.Add(New JProperty("Pedido", ObsPedido.ToString())) json.Add(New JProperty("Almacen", ObsInv.ToString())) Return json End Function #Region "V A L I D A - D A T O S" Private Function ValidaUsuarioSistema(CveEmpresa As Integer) As Usuario Dim UsuarioActual As Usuario = Nothing Dim NombreCadena As String = ClsPaginas.GlobalNombreCadenaConexion(CveEmpresa) Dim ObjUsuarios As New ClsSisUsuarioAutenticacion(NombreCadena:=NombreCadena) UsuarioActual = ObjUsuarios.GetUsuarioDetalle(100) If UsuarioActual IsNot Nothing Then Dim Usuario = ObjUsuarios.DtResultados.Rows(0)("Usuario").ToString() Dim Contrasenia = ObjUsuarios.DtResultados.Rows(0)("Contraseña").ToString() UsuarioActual = ObjUsuarios.ValidaUsuario(Usuario, Contrasenia, CveEmpresa:=CveEmpresa) End If ObjUsuarios.Dispose() Return UsuarioActual End Function Private Sub CreaObjetoEmpresa(ByRef UsuarioActual As Usuario) Dim ObjEmpresa As New ClsSisEmpresas() If ObjEmpresa.GetEmpresas(UsuarioActual.CveEmpresa, "-1", "-1", "-1", "-1") Then If ObjEmpresa.GetEmpresasFuncionalidades(UsuarioActual.CveEmpresa) Then Dim dttmp As Data.DataTable = ObjEmpresa.DtResultados Dim EmpresasFuncionalidades As New HybridDictionary For Each Row As Data.DataRow In dttmp.Rows EmpresasFuncionalidades.Add(Convert.ToInt32(Row("CveFuncionalidad")), Row("Valor").ToString) Next ObjEmpresa.Empresa.SetFuncionalidades(EmpresasFuncionalidades) End If UsuarioActual.Empresa = ObjEmpresa.Empresa End If ObjEmpresa.Dispose() End Sub #End Region #Region "D E F I N I R - O B J E T O S" Private Function CreaFactura(Resp As Modelos.Factura.MMensajeFactura, UsuarioActual As Usuario, DTRemisionesPS As DataTable, CveCliente As Integer, CveSubProyecto As Integer, CveMoneda As Integer, DatosRemisiones As JObject, FechaI As DateTime, FechaF As DateTime) As Modelos.Factura Try Dim Folio As String = "" Dim Serie As String = "" Dim ObjFolios As New ClsGralFolios() If ObjFolios.GetFolios("Ing", UsuarioActual.CveEmpresa) Then Dim DT As DataTable = ObjFolios.DtResultados.FiltraParametros(String.Format(" Estado = 'Activo' AND CveSubProyecto = {0}", CveSubProyecto)) If DT.Rows.Count > 0 Then Serie = DT.Rows(0)("Serie").ToString() Folio = DT.Rows(0)("FActual").ToString() End If DT.Dispose() End If ObjFolios.Dispose() Dim ObjFactura As New Modelos.Factura(UsuarioActual) ObjFactura.TipoMensajeRespuesta = Modelos.TipoMensajeRespuesta.TextoLimpio ObjFactura.Serie = Serie ObjFactura.Folio = Folio.ToEntero() ObjFactura.TipoMensajeRespuesta = TipoMensajeRespuesta.TextoLimpio ObjFactura.Version = "4.0" ObjFactura.CveUsuario = UsuarioActual.CveUsuario ObjFactura.CveEmpresa = UsuarioActual.CveEmpresa ObjFactura.CveMoneda = CveMoneda ObjFactura.Moneda = ClsPaginas.GlobalDTMonedas.FiltroPrimeroValor("Moneda", String.Format("CveMoneda = {0} ", CveMoneda)) ObjFactura.MonedaSAT = ClsPaginas.GlobalDTMonedas.FiltroPrimeroValor("AbreviaturaSAT", String.Format("CveMoneda = {0} ", CveMoneda)) ObjFactura.TipoDocto = "Ing" 'ObjFactura.CveMesa = -1 ObjFactura.Fecha = ClsPaginas.NowADS() ObjFactura.CvePrePoliza = -1 ObjFactura.FechaPago = ClsPaginas.NowADS() ObjFactura.MotivoDescuento = "" ObjFactura.FechaEjecucion = ClsPaginas.NowADS() ObjFactura.UsuarioCreo = UsuarioActual.Usuario ObjFactura.CveCondicionEntrega = -1 ObjFactura.CondicionesPago = 0 ObjFactura.TipoDocumento = "Ingresos" ObjFactura.ConvertirPesos = False ObjFactura.CveSubProyecto = CveSubProyecto ObjFactura.CveSubProyectoCobranza = CveSubProyecto ObjFactura.CveSubProyectoEjecucion = CveSubProyecto ObjFactura.SubProyecto = New SubProyectoModel(ClsPaginas.GlobalDTSubProyectos(UsuarioActual.CveEmpresa).FiltroPrimero(String.Format("CveSubProyecto = {0}", CveSubProyecto))) ObjFactura.SubProyectoMatriz = New SubProyectoModel(ClsPaginas.GlobalDTSubProyectos(UsuarioActual.CveEmpresa, CveSubProyecto:=-1 ).FiltroPrimero("TipoSucursal=1")) 'CLIENTE ObjFactura.CveCliente = CveCliente ObjFactura.SetCliente() ObjFactura.CveAlmacen = -1 Dim ObjCliente As New ClsClientes If ObjCliente.GetClientes(CveCliente, "-1", "-1", "-1", "-1", "-1", "-1", -1, UsuarioActual.CveEmpresa, -1, TipoCliente:=-1) Then If ObjCliente.DtResultados.Rows.Count > 0 Then ObjFactura.CveFormaPago = ObjCliente.CveFormaPago ObjFactura.FormaPago = ClsPaginas.GlobalDTVtaFormaPago.FiltroPrimeroValor("FormaPago", String.Format("CveFormaPago = {0}", ObjCliente.CveFormaPago)) ObjFactura.ClaveFormaPagoSAT = ClsPaginas.GlobalDTVtaFormaPago.FiltroPrimeroValor("ClaveFormaPagoSAT", String.Format("CveFormaPago = {0}", ObjCliente.CveFormaPago)) ObjFactura.CveMetodoPago = ObjCliente.CveMetodoPago ObjFactura.MetodoPago = ClsPaginas.GlobalDTVtaMetodoPago.FiltroPrimeroValor("MetodoPago", String.Format("CveMetodoPago = {0}", ObjCliente.CveMetodoPago)) ObjFactura.ClaveMetodoPagoSAT = ClsPaginas.GlobalDTVtaMetodoPago.FiltroPrimeroValor("ClaveMetodoPagoSAT", String.Format("CveMetodoPago = {0}", ObjCliente.CveMetodoPago)) ObjFactura.CveUsoCFDI = ObjCliente.CveUsoCFDI ObjFactura.UsoCFDI = ClsPaginas.GlobalDTSATUsosCFDI.FiltroPrimeroValor("Descripcion", String.Format("CveUsoCFDI = {0}", ObjCliente.CveUsoCFDI)) ObjFactura.ClaveUsoCFDISAT = ClsPaginas.GlobalDTSATUsosCFDI.FiltroPrimeroValor("UsoCFDI", String.Format("CveUsoCFDI = {0}", ObjCliente.CveUsoCFDI)) 'ObjFactura.CveMetodoPago = ObjCliente.CveMetodoPago 'If GlobalDTMetodosPago.FiltraParametros(String.Format("CveMetodoPago = {0}", ObjCliente.CveMetodoPago)).Rows.Count > 0 Then ' ObjFactura.MetodoPago = GlobalDTMetodosPago.FiltraParametros(String.Format("CveMetodoPago = {0}", ObjCliente.CveMetodoPago)).Rows(0)("MetodoPago").ToString 'Else ' ObjFactura.CveMetodoPago = 1 ' ObjFactura.MetodoPago = "Efectivo" 'End If End If End If If ObjCliente.GetSucursales(CveCliente) Then If ObjCliente.DtResultados.Rows.Count > 0 Then ObjFactura.CveClienteSucursal = If(String.IsNullOrEmpty(ObjCliente.DtResultados.FiltroPrimeroValor("CveClienteSucursal", "Estatus = 'Activo'")), -1, ObjCliente.DtResultados.FiltroPrimeroValor("CveClienteSucursal", "Estatus = 'Activo'").ToEntero()) Else ObjFactura.CveClienteSucursal = -1 End If End If ObjCliente.Dispose() 'DETALLES ObjFactura.DtDetalle = CreaDTDetalle(Resp, UsuarioActual, DTRemisionesPS) ObjFactura.DtRemisionesPS = DTRemisionesPS Dim TotalImporte As Decimal = ObjFactura.DtDetalle.SUM("TotalImporte") Dim ImporteIVA As Decimal = ObjFactura.DtDetalle.SUM("ImporteIVA") Dim ImporteRetIVA As Decimal = ObjFactura.DtDetalle.SUM("ImporteRetIVA") Dim ImporteRetISR As Decimal = ObjFactura.DtDetalle.SUM("ImporteRetISR") Dim ImporteIEPS As Decimal = ObjFactura.DtDetalle.SUM("ImporteIEPS") Dim Descuento As Decimal = ObjFactura.DtDetalle.SUM("Descuento") Dim Amortizacion As Decimal = 0 Dim Total As Decimal = (TotalImporte + ImporteIVA + ImporteIEPS) - (ImporteRetIVA + ImporteRetISR + Descuento + Amortizacion) 'DETALLES ObjFactura.SubTotal = TotalImporte ObjFactura.Descuento = Descuento ObjFactura.Amortizacion = Amortizacion ObjFactura.IVA = ImporteIVA ObjFactura.RetIVA = ImporteRetIVA ObjFactura.RetISR = ImporteRetISR ObjFactura.IEPS = ImporteIEPS ObjFactura.Total = Total ObjFactura.TotalOtrosConceptos = 0 'VALIDA PROMOCIONES Y EXISTENCIAS Dim ObjVentas As New ClsVentas If ObjVentas.GetPromocionesPS(-1, ClsPaginas.NowADS(), CveSubProyecto, ObjFactura.CveCliente, ObjFactura.CveVendedor, 1, UsuarioActual.CveEmpresa) Then ObjFactura.DtPromociones = ObjVentas.DtResultados.Copy() End If If ObjVentas.GetRemisionesSinFacturar(FechaI.ToShortDateString, FechaF.ToShortDateString, CveCliente, -1, 1, -1) Then ObjFactura.DtRemisiones = ObjVentas.DtResultados.FiltraParametros("CveContrato = 0") End If ObjVentas.Dispose() ObjFactura.Observaciones = DatosRemisiones("Observaciones").ToString() ObjFactura.OrdenCompra = DatosRemisiones("OrdenCompra").ToString() ObjFactura.PedidoContrato = DatosRemisiones("Pedido").ToString() ObjFactura.ObservacionesAlmacen = DatosRemisiones("Almacen").ToString() For Each Venta As JObject In DatosRemisiones("Ventas") ObjFactura.RemisionesLista.Add(Venta("CveVenta").ToString.ToEntero) Next ObjFactura.Timbre = PreParaTimbre(ObjFactura) ObjFactura.FemsaFactura = New Modelos.FemsaFactura() With { .AplicaFEMSA = False, .FEMSA_Version = 1 } Return ObjFactura Catch ex As Exception Resp.Mensajes.Add(ex.ToString()) Return Nothing End Try End Function Private Function PreParaTimbre(Obj As Modelos.Factura) As CFDITimbre Dim Timbre As New CFDITimbre Timbre.Comprobante.TipoComprobante = If(Obj.TipoDocto.Contiene("Ing", "Ant"), "I", If(Obj.TipoDocto.Contiene("Egs", "Dev"), "E", "")) Timbre.Comprobante.Folio = Obj.Folio.ToString Timbre.Comprobante.Serie = Obj.Serie Timbre.Comprobante.Fecha = Obj.FechaCP Timbre.Comprobante.FormadePago = Obj.ClaveFormaPagoSAT Timbre.Comprobante.CondicionesdePago = Obj.FormaPago Timbre.Comprobante.MetodoPago = Obj.ClaveMetodoPagoSAT Timbre.Comprobante.Subtotal = Obj.SubTotal Timbre.Comprobante.Descuentos = Obj.Descuento Timbre.Comprobante.Moneda = Obj.MonedaSAT Timbre.Comprobante.TipoCambio = If(Obj.CveMoneda = 1, "1", Obj.TipoCambio.ToString) Timbre.Comprobante.Total = Obj.Total Timbre.Comprobante.LugarExpedicion = Obj.SubProyecto.CP Timbre.Comprobante.Confirmacion = "" Timbre.Receptor.RFC = Obj.Cliente.RFC Timbre.Receptor.Nombre = Obj.Cliente.Nombre Timbre.Receptor.ResidenciaFiscal = "" Timbre.Receptor.NumeroRegistroTributario = "" Timbre.Receptor.UsoCFDI = Obj.ClaveUsoCFDISAT If Obj.CveTipoRelacion > 0 Then Select Case Obj.CveTipoRelacion Case 1 Timbre.CFDIRelacionados.TipoRelacion = "01" Timbre.CFDIRelacionados.TipoRelacionTexto = "01-Nota de Crédito aplicada a Ingreso" Case 2 Timbre.CFDIRelacionados.TipoRelacion = "02" Timbre.CFDIRelacionados.TipoRelacionTexto = "02-Nota de débito de los documentos relacionados" Case 3 Timbre.CFDIRelacionados.TipoRelacion = "03" Timbre.CFDIRelacionados.TipoRelacionTexto = "03-Devolución aplicada a Ingreso" Case 4 Timbre.CFDIRelacionados.TipoRelacion = "04" Timbre.CFDIRelacionados.TipoRelacionTexto = "04-Refacturación de Ingreso" Case 7 Timbre.CFDIRelacionados.TipoRelacion = "07" Timbre.CFDIRelacionados.TipoRelacionTexto = "07-CFDI por aplicación de anticipo" Case 8 Timbre.CFDIRelacionados.TipoRelacion = "08" Timbre.CFDIRelacionados.TipoRelacionTexto = "08-Factura generada por pagos en parcialidades " Case 9 Timbre.CFDIRelacionados.TipoRelacion = "09" Timbre.CFDIRelacionados.TipoRelacionTexto = "09-Factura generada por pagos diferidos" End Select End If Dim totSubTotal As Decimal = Obj.SubTotal Dim totIVA As Decimal = Obj.IVA Dim totRetIVA As Decimal = Obj.RetIVA Dim totRetISR As Decimal = Obj.RetISR Dim i As Integer = 1 'DETALLES Dim tPS As String = "" For Each drr As DataRow In Obj.DtDetalle.Rows If drr("PS").ToString.Length = 1 Then tPS = drr("Obs").ToString Else If drr("PS").ToString.Length = 0 Then tPS = "" Else tPS = String.Format("{0} {1}", drr("PS"), drr("Obs")) End If End If 'CONDICIONANTE, ESPECIAL If Obj.CveEmpresa = 15 Then drr("UM") = "" 'LES COMENTAN QUE NO DEBE IR LA ETIQUETA DE LA UNIDAD EN EL PRODUCTO Dim concepto As New CFDIConceptos With {.Cantidad = drr("Cantidad").ToString.ToDecimal, .Descripcion = tPS, .ValorUnitario = drr("PU").ToString.ToDecimal, .Importe = drr("TotalImporte").ToString.ToDecimal, .Descuento = drr("Descuento").ToString.ToDecimal, .Unidad = drr("UM").ToString, .ClaveUnidad = drr("SATClaveUM").ToString, .ClaveProdServ = drr("SATClaveProdServ").ToString, .Noidentificacion = drr("Noidentificacion").ToString, .CuentaPredial = drr("CuentaPredial").ToString} 'VERIFICA SUMA SUBTOTALES If i = Obj.DtDetalle.Rows.Count AndAlso totSubTotal <> concepto.Importe Then 'PROCESO DE AJUSTA DE DECIMALES concepto.Importe = totSubTotal End If totSubTotal = totSubTotal - concepto.Importe 'SIEMPRE ESTAMOS AGREGANDO EL IVA concepto.Impuestos.Add(New CFDIConceptosImpuestos With {.TrasladooRetencion = "T", .Base = concepto.Importe - concepto.Descuento, .TasaOCuota = drr("PorcentajeIVA").ToString.ToDecimal, .Impuesto = "002", .Importe = drr("ImporteIVA").ToString.ToDecimal}) If drr("ImporteIEPS").ToString.ToDouble > 0 Then concepto.Impuestos.Add(New CFDIConceptosImpuestos With {.TrasladooRetencion = "T", .Base = concepto.Importe - concepto.Descuento, .TasaOCuota = drr("PorcentajeIEPS").ToString.ToDecimal, .Impuesto = "003", .Importe = drr("ImporteIEPS").ToString.ToDecimal}) End If If drr("ImporteRetIVA").ToString.ToDouble > 0 Then 'si hay retenciones concepto.Impuestos.Add(New CFDIConceptosImpuestos With {.TrasladooRetencion = "R", .Base = concepto.Importe - concepto.Descuento, .TasaOCuota = drr("PorcentajeRetIVA").ToString.ToDecimal, .Impuesto = "002", .Importe = drr("ImporteRetIVA").ToString.ToDecimal}) End If If drr("ImporteRetISR").ToString.ToDouble > 0 Then 'retención de ISR concepto.Impuestos.Add(New CFDIConceptosImpuestos With {.TrasladooRetencion = "R", .Base = concepto.Importe - concepto.Descuento, .TasaOCuota = drr("PorcentajeRetISR").ToString.ToDecimal, .Impuesto = "001", .Importe = drr("ImporteRetISR").ToString.ToDecimal}) End If Timbre.Conceptos.Add(concepto) i += 1 Next Return Timbre End Function Private Function CreaDTDetalle(ByRef Retorno As Modelos.Factura.MMensajeFactura, UsuarioActual As Usuario, DtRemisionesPS As DataTable) As DataTable Dim TmpDT As New DataTable TmpDT.Columns.Add("CveVenta", GetType(Integer)) TmpDT.Columns.Add("Consec", GetType(Integer)) TmpDT.Columns.Add("Cantidad", GetType(Decimal)) TmpDT.Columns.Add("Codigo", GetType(String)) TmpDT.Columns.Add("CveUM", GetType(Integer)) TmpDT.Columns.Add("UM", GetType(String)) TmpDT.Columns.Add("SATClaveUM", GetType(String)) TmpDT.Columns.Add("CveClasificacion", GetType(Integer)) TmpDT.Columns.Add("Clasificacion", GetType(String)) TmpDT.Columns.Add("CvePS", GetType(Integer)) TmpDT.Columns.Add("PS", GetType(String)) TmpDT.Columns.Add("CodigoPS", GetType(String)) TmpDT.Columns.Add("SATClaveProdServ", GetType(String)) TmpDT.Columns.Add("NoIdentificacion", GetType(String)) TmpDT.Columns.Add("CveTipoPS", GetType(Integer)) TmpDT.Columns.Add("CveTipoInvPS", GetType(Integer)) TmpDT.Columns.Add("Serie", GetType(String)) TmpDT.Columns.Add("CuentaPredial", GetType(String)) TmpDT.Columns.Add("Obs", GetType(String)) TmpDT.Columns.Add("TiempoEntrega", GetType(String)) TmpDT.Columns.Add("PU", GetType(Decimal)) TmpDT.Columns.Add("IVA", GetType(Decimal)) TmpDT.Columns.Add("ImporteIVA", GetType(Decimal)) TmpDT.Columns.Add("PorcentajeIVA", GetType(Decimal)) TmpDT.Columns.Add("ImporteRetIVA", GetType(Decimal)) TmpDT.Columns.Add("ImporteRetISR", GetType(Decimal)) TmpDT.Columns.Add("PorcentajeRetIVA", GetType(Decimal)) TmpDT.Columns.Add("PorcentajeRetISR", GetType(Decimal)) TmpDT.Columns.Add("ImporteIEPS", GetType(Decimal)) TmpDT.Columns.Add("IEPS", GetType(Decimal)) TmpDT.Columns.Add("PorcentajeIEPS", GetType(Decimal)) TmpDT.Columns.Add("Descuento", GetType(Decimal)) TmpDT.Columns.Add("TipoDescuento", GetType(Integer)) TmpDT.Columns.Add("TotalImporte", GetType(Decimal)) TmpDT.Columns.Add("Total", GetType(Decimal)) 'Para uso del módulo contable TmpDT.Columns.Add("AsientoContableVentas", GetType(Integer)) TmpDT.Columns.Add("AplicaParaConcepto", GetType(Boolean)) TmpDT.Columns.Add("CveProyecto", GetType(Integer)) TmpDT.Columns.Add("Proyecto", GetType(String)) TmpDT.Columns.Add("CveSubProyecto", GetType(Integer)) TmpDT.Columns.Add("SubProyecto", GetType(String)) 'TipoDescuento: 1 = Descuento * PU; 2 = Descuento por Total del concepto TmpDT.Columns.Add("CvePresupuestoIngreso", GetType(Integer)) TmpDT.Columns.Add("CveFuenteRecaudacion", GetType(Integer)) 'Contratos TmpDT.Columns.Add("CveContratoDetalle", GetType(Integer)) 'Remisiones a Facturas TmpDT.Columns.Add("CveVentaDetalle", GetType(Integer)) TmpDT.Columns.Add("CveVentaDetalleRemision", GetType(Integer)) TmpDT.Columns.Add("CveVentaDetalleCotizacion", GetType(Integer)) 'Pedido2 a Facturas TmpDT.Columns.Add("CveVentaDetallePedido2", GetType(Integer)) TmpDT.Columns.Add("Origen", GetType(Integer)) 'Ordenes Servicio TmpDT.Columns.Add("CveOS", GetType(Integer)) TmpDT.Columns.Add("CveOSDetalle", GetType(Integer)) TmpDT.Columns.Add("SeFacturara", GetType(Integer)) TmpDT.Columns.Add("Folio", GetType(Integer)) TmpDT.Columns.Add("Estatus", GetType(String)) 'Ordenamiento TmpDT.Columns.Add("Orden", GetType(Integer)) TmpDT.Columns.Add("TipoDocto", GetType(String)) 'OC TmpDT.Columns.Add("CveOrdenCompraDetalle", GetType(Integer)) TmpDT.Columns.Add("EntregaDirecta", GetType(Integer)) TmpDT.Columns.Add("CveMovimientoDetallePedido", GetType(Integer)) TmpDT.Columns.Add("CantidadFacturadaRem", GetType(Decimal)) TmpDT.Columns.Add("CantidadFacturadaCot", GetType(Decimal)) TmpDT.Columns.Add("CantidadInventario", GetType(Decimal)) TmpDT.Columns.Add("ClaveSATFraccionArancelaria", GetType(String)) TmpDT.Columns.Add("ClaveSATUnidadAduana", GetType(String)) TmpDT.Columns.Add("ClaveSATFraccionArancelariaDescripcion", GetType(String)) TmpDT.Columns.Add("ClaveSATUnidadAduanaDescripcion", GetType(String)) TmpDT.Columns.Add("CveTamaño", GetType(Integer)) Try For Each Dr As DataRow In DtRemisionesPS.Select() Dim Row As DataRow = AgregarProductoServicio(Retorno, UsuarioActual, TmpDT, Dr("Consec").ToString.ToEntero(), Dr("Cantidad").ToString.ToDecimal(), Dr("CveUM").ToString.ToEntero, Dr("UM").ToString, Dr("CveClasificacion").ToString.ToEntero, Dr("Clasificacion").ToString, Dr("CvePS").ToString.ToEntero, Dr("PS").ToString, Dr("Obs").ToString, Dr("PU").ToString.ToDecimal, Dr("Descuento").ToString.ToDecimal, Dr("CveSubProyecto").ToString.ToEntero, CveVentaDetalle:=-1, CveContratoDetalle:=Dr("CveContratoDetalle").ToString.ToEntero, CveVentaDetalleRemision:=Dr("CveVentaDetalle").ToString.ToEntero, RegeneraIEPS:=True) If Row IsNot Nothing Then TmpDT.Rows.Add(Row) Else Retorno.Mensajes.Add(String.Format("No se pudo agregar el producto/servicio: {0}", Dr("PS").ToString())) End If Next Catch ex As Exception Retorno.Mensajes.Add(ex.ToString()) End Try Return TmpDT End Function Private Function AgregarProductoServicio(ByRef Retorno As Modelos.Factura.MMensajeFactura, UsuarioActual As Usuario, TmpDT As DataTable, Consec As Integer, Cantidad As Decimal, CveUM As Integer, UM As String, CveClasificacion As Integer, Clasificacion As String, CvePS As Integer, PS As String, Obs As String, PU As Decimal, Descuento As Decimal, CveSubProyecto As Integer, Optional Serie As String = "", Optional TiempoEntrega As String = "", Optional EntregaDirecta As Integer = 0, Optional CveContratoDetalle As Integer = 0, Optional CveVentaDetalle As Integer = 0, Optional CveMovimientoDetallePedido As Integer = 0, Optional CveOrdenCompraDetalle As Integer = 0, Optional CveVentaDetalleRemision As Integer = 0, Optional CveVentaDetalleCotizacion As Integer = 0, Optional CuentaPredial As String = "", Optional RegeneraIEPS As Boolean = True, Optional CveVentaDetallePedido2 As Integer = 0, Optional ClienteRetIVA As Double = 0, Optional ClienteRetISR As Double = 0, Optional ClienteDesglosaIEPS As Boolean = True) As DataRow Dim DrPS As DataRow = Nothing DrPS = ClsPaginas.GlobalDTPS(UsuarioActual.CveEmpresa, CvePS:=CvePS).FiltroPrimero("") ' Estado = -1 If DrPS Is Nothing Then Retorno.Mensajes.Add("Ocurrió un error al cargar la información del Producto. Por favor vuelva a intentar.") Return Nothing End If 'verifica si tiene ventaminima If Cantidad > 0 AndAlso DrPS("VentaMinima").ToString.ToDouble() > 0 Then 'verifico que la cantidad sea multiplo de venta minima, es decir ventaminima =5, solo puede vender 5,10,15... If Cantidad < DrPS("VentaMinima").ToString.ToDouble() Then Retorno.Mensajes.Add("La cantidad es menor que la venta minima") Return Nothing End If End If If (DrPS("SATClaveUnidadMedida").ToString = "" Or DrPS("SATClavePS").ToString = "") Then 'VALIDA CLAVESAT If DrPS("SATClavePS").ToString = "" Then Retorno.Mensajes.Add(String.Format("{0}-{1}: Sin producto SAT
", DrPS("Codigo").ToString, DrPS("PS").ToString)) Return Nothing ElseIf DrPS("SATClaveUnidadMedida").ToString = "" Then Retorno.Mensajes.Add(String.Format("{0}-{1}: Sin Unidad Medida SAT
", DrPS("Codigo").ToString, DrPS("PS").ToString)) Return Nothing End If End If If Not ClienteDesglosaIEPS Then If Not RegeneraIEPS Then PU = PU * (1 + DrPS("IEPSPorcentaje").ToString.ToDecimal) End If DrPS("IEPSPorcentaje") = 0 End If Dim Row As DataRow = Nothing Dim TotalCalculableImpuestos As Decimal = 0 PU = Math.Round(PU, 6) ' el precio unitario puede llevar hasta 6 decimales permitidos Dim DrSubProyecto As DataRow = ClsPaginas.GlobalDTSubProyectos(UsuarioActual.CveEmpresa, CveSubProyecto).Rows(0) Row = TmpDT.NewRow() Row("CveProyecto") = DrSubProyecto("CveProyecto").ToString().ToEntero() Row("Proyecto") = DrSubProyecto("Proyecto").ToString() Row("CveSubProyecto") = CveSubProyecto Row("SubProyecto") = DrSubProyecto("SubProyecto").ToString() Row("Serie") = Serie Row("TiempoEntrega") = TiempoEntrega Row("Orden") = TmpDT.Rows.Count + 1 Row("Cantidad") = Cantidad Row("CveUM") = CveUM Row("UM") = UM Row("CveClasificacion") = CveClasificacion Row("Clasificacion") = Clasificacion Row("CvePS") = CvePS Row("Obs") = Obs TotalCalculableImpuestos = (Cantidad * PU) - Descuento Row("PU") = PU Row("Codigo") = DrPS("Codigo") Row("NoIdentificacion") = DrPS("Codigo") Row("ClaveSATFraccionArancelaria") = DrPS("ClaveSATFraccionArancelaria") Row("ClaveSATUnidadAduana") = DrPS("ClaveSATUnidadAduana") Row("ClaveSATFraccionArancelariaDescripcion") = DrPS("ClaveSATFraccionArancelariaDescripcion") Row("ClaveSATUnidadAduanaDescripcion") = DrPS("ClaveSATUnidadAduanaDescripcion") Row("Consec") = Consec Row("PS") = DrPS("PS") Row("CodigoPS") = DrPS("PSCodigo").ToString Row("CveTipoPS") = DrPS("CveTipoPS") Row("CveTipoInvPS") = DrPS("Inv_CveMetodoInventario") Row("CveTamaño") = DrPS("CveTamaño") If CveClasificacion <= 0 Then Row("CveClasificacion") = DrPS("CveClasificacion") If Clasificacion = "" Then Row("Clasificacion") = DrPS("Clasificacion") If DrPS("IVA").ToString.Contiene("-1", "") Then Row("PorcentajeIVA") = DrSubProyecto("IVA") Else Row("PorcentajeIVA") = DrPS("IVA") End If Row("IVA") = Row("PorcentajeIVA") Row("ImporteIVA") = Math.Round(Row("PorcentajeIVA").ToString.ToDecimal * TotalCalculableImpuestos, 2) Row("ImporteRetIVA") = Math.Round(ClienteRetIVA * TotalCalculableImpuestos, 2) Row("ImporteRetISR") = Math.Round(ClienteRetISR * TotalCalculableImpuestos, 2) Row("PorcentajeRetIVA") = ClienteRetIVA Row("PorcentajeRetISR") = ClienteRetISR Row("PorcentajeIEPS") = DrPS("IEPSPorcentaje") Row("ImporteIEPS") = Math.Round(DrPS("IEPSPorcentaje").ToString.ToDecimal * TotalCalculableImpuestos, 2) Row("IEPS") = Row("ImporteIEPS") Row("Descuento") = Math.Round(Descuento, 2) Row("TipoDescuento") = "2" Row("Total") = Cantidad * PU Row("TotalImporte") = Math.Round(Cantidad * PU, 2) Row("SATClaveProdServ") = DrPS("SATClavePS") Row("SATClaveUM") = DrPS("SATClaveUnidadMedida") Row("EntregaDirecta") = EntregaDirecta 'Contratos Row("CveContratoDetalle") = CveContratoDetalle Row("CveVentaDetalle") = CveVentaDetalle Row("CveMovimientoDetallePedido") = CveMovimientoDetallePedido Row("CveOrdenCompraDetalle") = CveOrdenCompraDetalle Row("CveVentaDetalleRemision") = CveVentaDetalleRemision Row("CveVentaDetalleCotizacion") = CveVentaDetalleCotizacion Row("CveVentaDetallePedido2") = CveVentaDetallePedido2 Row("CuentaPredial") = CuentaPredial 'RECARGAR GV Return Row End Function #End Region #Region "E N V I O - C O R R E O" Private Sub EnviarCorreo(Objfactura As Modelos.Factura, UsuarioActual As Usuario) Try Dim Hilo As New System.Threading.Thread(Sub() EnviarCorreoFactura(Objfactura, UsuarioActual)) Hilo.Start() Catch ex As Exception OnError("Ocurrió error al mandar el correo de facturación", ex) End Try End Sub Private Function DescargarFactura(CveVenta As Integer, CveEmpresa As Integer) As Byte() Dim Url = New Uri(String.Format("{0}Compras/PopUpVerFactura.aspx?P={1}", ClsPaginas.UrlSitio, Encripta(String.Format("OP=VTA&CVEVENTA={0}&PAG=1&GUARDAR=1", CveVenta)))) Dim File As Byte() = Nothing Try Using httpClient As New HttpClient() httpClient.Timeout = New TimeSpan(0, 15, 0) Using request As New HttpRequestMessage(HttpMethod.Get, Url) request.Headers.Add("ADSToken", Encripta(String.Format("CVEEMPRESA={0}&TICKS={1}&CVEUSUARIO=100", CveEmpresa, DateTime.UtcNow.Ticks))) Dim response = httpClient.SendAsync(request).Result If response.StatusCode = Net.HttpStatusCode.OK Then File = response.Content.ReadAsByteArrayAsync().Result End If End Using End Using Catch ex As Exception File = Nothing OnError("Ocurrió un error al descargar la factura", ex) End Try Return File End Function Private Sub EnviarCorreoFactura(ObjFactura As Modelos.Factura, UsuarioActual As Usuario) Dim ObjMail As New ClsSisMail() Dim ObjVentas As New ClsVentas Dim ObjCliente As New ClsClientes Dim Mail As String = "" Dim MailCC As String = "" Dim ArchivoXML As String = "" Dim ArchivoPDF As String = "" Dim ArchivoPDFBytes As Byte() = Nothing Dim ExistePDF As Boolean = False Try ArchivoXML = String.Format("{0}XML\{1}\{2}.xml", UsuarioActual.Empresa.Ruta, ObjFactura.TipoDocto, ObjFactura.SerieFolio) ArchivoPDF = String.Format("{0}PDF\{1}\{2}.pdf", UsuarioActual.Empresa.Ruta, ObjFactura.TipoDocto, ObjFactura.SerieFolio) If Not File.Exists(ArchivoPDF) Then ArchivoPDFBytes = DescargarFactura(ObjFactura.CveVenta, ObjFactura.CveEmpresa) Else ExistePDF = True End If If ObjFactura.CveClienteSucursal > 0 Then If ObjCliente.GetSucursales(ObjFactura.CveCliente, ObjFactura.CveClienteSucursal) Then If ObjCliente.DtResultados.Rows.Count > 0 Then Dim Correo As String = ObjCliente.DtResultados.Rows(0)("Correo").ToString If Correo.Trim.Length > 0 Then Mail = Correo End If MailCC = ObjCliente.NotificarA End If End If Else If ObjCliente.GetClientes(ObjFactura.CveCliente, "-1", "-1", "-1", "-1", "-1", "-1", -1, UsuarioActual.CveEmpresa, TipoCliente:=-1) Then If ObjCliente.DtResultados.Rows.Count > 0 Then Mail = If(ObjFactura.TipoDocto = "Cot", ObjCliente.MailCotizacion, ObjCliente.Mail) End If End If End If Catch ex As Exception OnError("Ocurrió un error al obtener el correo", ex) Finally ObjCliente.Dispose() End Try If Not String.IsNullOrEmpty(Mail) Then Try Dim Asunto As String = String.Empty Dim Cuerpo As String = String.Empty Dim ResultadoMail As Integer = 0 Dim TipoComprobante As String = "" If ObjFactura.TipoDocto = "Ing" Then TipoComprobante = "Factura" If ObjFactura.TipoDocto = "Egs" Then TipoComprobante = "Nota de Crédito" If ObjFactura.TipoDocto = "Dev" Then TipoComprobante = "Nota de Devolución" If ObjFactura.TipoDocto = "Rem" Then TipoComprobante = "Remisión" If ObjFactura.TipoDocto = "Cot" Then TipoComprobante = "Cotización" If ObjFactura.TipoDocto = "Ant" Then TipoComprobante = "Anticipo" If UsuarioActual.Empresa.PlantillaMailVenta.Trim.Length > 0 Then Cuerpo = UsuarioActual.Empresa.PlantillaMailVenta Cuerpo = Cuerpo.Replace("{""NombreEmpresa""}", UsuarioActual.Empresa.Empresa) Cuerpo = Cuerpo.Replace("{""NombreCliente""}", ObjFactura.Cliente.NombreComercial) Cuerpo = Cuerpo.Replace("{""TipoDocumento""}", TipoComprobante) Cuerpo = Cuerpo.Replace("{""Fecha""}", ObjFactura.Fecha.ToString("dd/MM/yyyy")) Cuerpo = Cuerpo.Replace("{""Total""}", ObjFactura.Total.ToString) Cuerpo = Cuerpo.Replace("{""FechaVencimiento""}", ObjFactura.FechaVencimiento.ToString("dd/MM/yyyy")) Cuerpo = Cuerpo.Replace("{""SerieFolio""}", ObjFactura.SerieFolio) End If If UsuarioActual.Empresa.AsuntoPlantillaMailVenta.Trim.Length > 0 Then Asunto = UsuarioActual.Empresa.AsuntoPlantillaMailVenta Asunto = Asunto.Replace("{""TipoDocumento""}", TipoComprobante) Asunto = Asunto.Replace("{""Sucursal""}", ObjFactura.SubProyecto.SubProyecto) Asunto = Asunto.Replace("{""SerieFolio""}", ObjFactura.SerieFolio) End If Dim LSRutasMail As New List(Of ClsSisMail.ArchivoMail) LSRutasMail.Add(New ClsSisMail.ArchivoMail With {.Ruta = ArchivoXML}) If ExistePDF Then LSRutasMail.Add(New ClsSisMail.ArchivoMail With {.Ruta = ArchivoPDF}) Else LSRutasMail.Add(New ClsSisMail.ArchivoMail With {.ArchivoBinario = ArchivoPDFBytes, .NombreArchivo = String.Format("{0}.pdf", ObjFactura.SerieFolio)}) End If Dim DisplayName As String = "" If UsuarioActual.CveEmpresa = 119 Then DisplayName = "Facturación Agroquímicos JAM" If ObjMail.SendMail(UsuarioActual.Empresa, Mail, Asunto, Cuerpo, If(String.IsNullOrEmpty(MailCC), "", MailCC), LSRutasMail, Displayname:=DisplayName) Then ResultadoMail = 1 Else GuardaLogFacturacion($"No se envio el correo {Mail}, {Asunto}, {Cuerpo}, {MailCC},") GuardaLogFacturacion($"Ruta XML {ArchivoXML}") ResultadoMail = 3 End If ObjVentas.UpdateVentaMail(ResultadoMail, ObjFactura.CveVenta) Catch ex As Exception OnError("Ocurrió error al mandar el Mail", ex) GuardaLogFacturacion(ex.ToString()) ObjVentas.UpdateVentaMail(3, ObjFactura.CveVenta) Finally ObjVentas.Dispose() If ObjFactura IsNot Nothing Then ObjFactura.Dispose() End If End Try End If End Sub #End Region Public Sub GuardaLogFacturacion(Str As String) Dim ArchivoW As StreamWriter Dim strLineaTMP As String ' strLineaTMP = Chr(13) & Chr(10) & Day(NowADS()) & "/" & Month(NowADS()) & "/" & Year(NowADS()) & " " & Hour(NowADS()) & ":" & Minuto & ". " & Str & Chr(13) & Chr(10) strLineaTMP = String.Format("{0}{1}Log: {2}{3}:{4}", Chr(13), Chr(10), Str, ClsPaginas.NowADS().ToShortDateString, ClsPaginas.NowADS().ToShortTimeString) Try ArchivoW = New StreamWriter(String.Format("{0}\Log\LogFacturacion.txt", AppDomain.CurrentDomain.BaseDirectory), True, System.Text.Encoding.UTF8) Catch ex As UnauthorizedAccessException 'Alert("No hay permisos para guardar en el Log.", Extensiones.TipoMensaje.MsgError) Exit Sub Catch ex As Exception Exit Sub End Try Try ArchivoW.WriteLine(strLineaTMP) Catch End Try ArchivoW.Close() ArchivoW.Dispose() End Sub End Class