예제 #1
0
        public string ProcesarLoteFacturasBienesServicios(string EmpresaID, string xmlDocument)
        {
            #region Inicialización

            Settings oSettings = new Settings(EmpresaID);

            wsfe.Service afipFeService = new wsfe.Service();
            afipFeService.Url = oSettings.UrlAFIPwsfe;

            wsfe.FEAuthRequest afipObjFEAuthRequest = new wsfe.FEAuthRequest();
            wsfe.CbteTipo afipObjFELastCMType = new wsfe.CbteTipo();
            wsfe.FECAEResponse feResponse = new wsfe.FECAEResponse();

            ResponseBatch batchResponse = new ResponseBatch();
            RequestBatch loteDocs = new RequestBatch();

            string url = oSettings.UrlFEWebService;
            string SQLID = "0";
            string estadoDocumento = string.Empty;
            string cae = string.Empty;
            string FechaVencimiento = string.Empty;
            string strEquivalenciaErrorFields = string.Empty;

            bool bRegistrarInicio = false;
            bool bEquivalenciaError = false;

            //Cargar el lote recibido
            loteDocs.LoadXMLString(xmlDocument);

            #endregion

            #region Registrar Inicio

            try
            {
                bRegistrarInicio = sqlEngine.LogBatchStart(ref loteDocs);

                SQLID = loteDocs.RequestHeaders[0].SQLID;

                //DEBUG LINE
                if (Convert.ToBoolean( oSettings.ActivarDebug ))
                    Utils.Utils.DebugLine(Utils.Utils.SerializeObject(loteDocs), oSettings.PathDebug + "\\" + SQLID + "-P1.RequestBatch-" + DateTime.Now.Hour.ToString("00") + DateTime.Now.Minute.ToString("00") + DateTime.Now.Second.ToString("00") + DateTime.Now.Millisecond.ToString("000") + ".xml");
            }
            catch (Exception ex)
            {
                sqlEngine.LogError(SQLID, "0", "ProcesarLoteFacturasBienesServicios", ex.Message);
                bRegistrarInicio = false;
            }

            #endregion

            //Si pudo crear el registro en la base continuo
            if (bRegistrarInicio)
            {
                #region Verificar Login con AFIP

                AfipConnection afipConn = new AfipConnection("wsfe", oSettings);
                if (afipConn.ConnectionErrorDescription == string.Empty)
                {
                    //Inicializo el objeto AuthRequest de la Afip
                    afipObjFEAuthRequest.Cuit = afipConn.Cuit;
                    afipObjFEAuthRequest.Sign = afipConn.Sign;
                    afipObjFEAuthRequest.Token = afipConn.Token;
                }
                else
                {
                    try
                    {
                        sqlEngine.LogError(SQLID, "0", "AfipConnection", afipConn.ConnectionErrorDescription);
                        sqlEngine.LogBatchEnd(SQLID, "Error", cae, FechaVencimiento);
                    }
                    catch (Exception ex)
                    {
                        sqlEngine.LogError(SQLID, "0", "FEService-AFIP Login", "Error: " + ex.Message);
                    }
                }

                AfipFE afipFE = new AfipFE(ref afipFeService, ref afipObjFEAuthRequest, ref afipObjFELastCMType);

                #endregion

                if (afipConn.ConnectionErrorDescription == string.Empty)
                {
                    #region Buscar Equivalencias

                    bEquivalenciaError = BuscarEquivalencias(ref loteDocs, oSettings, ref strEquivalenciaErrorFields);

                    #endregion

                    //Si no hay errores de equivalencia continuo
                    if (!bEquivalenciaError)
                    {
                        #region Hacer el pedido a AFIP

                        try
                        {
                            if (afipConn.IsConnected)
                            {
                                feResponse = afipFE.FEAuthRequest(loteDocs, oSettings);

                                //DEBUG LINE
                                if (Convert.ToBoolean(oSettings.ActivarDebug))
                                    Utils.Utils.DebugLine(Utils.Utils.SerializeObject(feResponse), oSettings.PathDebug + "\\" + SQLID + "-P3.FEResponse-" + DateTime.Now.Hour.ToString("00") + DateTime.Now.Minute.ToString("00") + DateTime.Now.Second.ToString("00") + DateTime.Now.Millisecond.ToString("000") + ".xml");
                            }
                            else
                            {
                                sqlEngine.LogError(SQLID, "0", "Respuesta AFIP", "Sin Conexion. Descripcion: " + afipConn.ConnectionErrorDescription);
                                feResponse.Errors = new wsfe.Err[1];
                                feResponse.Errors[0] = new wsfe.Err();
                                feResponse.Errors[0].Code = 0;
                                feResponse.Errors[0].Msg = afipConn.ConnectionErrorDescription;
                            }
                        }
                        catch (Exception ex)
                        {
                            sqlEngine.LogError(SQLID, "0", "Respuesta AFIP", "Error: " + ex.Message);
                        }

                        #endregion
                    }
                }

                #region Armar y devolver respuesta

                //Armar info del lote
                if (feResponse.FeCabResp != null)
                {
                    batchResponse.BatchUniqueId = loteDocs.BatchUniqueId;
                    batchResponse.CUITInformante = feResponse.FeCabResp.Cuit.ToString();
                    batchResponse.FechaCAE = feResponse.FeCabResp.FchProceso;
                    batchResponse.CantidadComprobantes = feResponse.FeCabResp.CantReg.ToString();
                    batchResponse.Resultado = feResponse.FeCabResp.Resultado;

                    batchResponse.Reproceso = feResponse.FeCabResp.Reproceso;

                    if (feResponse.Errors != null && feResponse.Errors.Length > 0 && feResponse.Errors[0] != null)
                    {
                        batchResponse.CodigoError = feResponse.Errors[0].Code.ToString();
                        batchResponse.MensajeError = feResponse.Errors[0].Msg.ToString();
                    }
                }
                else
                {
                    batchResponse.BatchUniqueId = "0";
                    batchResponse.Resultado = "R";
                    batchResponse.CantidadComprobantes = loteDocs.CantidadComprobantes;

                    if (feResponse.Errors != null && feResponse.Errors.Length > 0 && feResponse.Errors[0] != null)
                    {
                        batchResponse.CodigoError = feResponse.Errors[0].Code.ToString();
                        batchResponse.MensajeError = feResponse.Errors[0].Msg.ToString();
                    }
                    else if(afipConn.ConnectionErrorDescription != string.Empty)
                    {
                        batchResponse.Resultado = "E";
                        batchResponse.CodigoError = "669";
                        batchResponse.MensajeError = afipConn.ConnectionErrorDescription;
                    }
                    else if (bEquivalenciaError)
                    {
                        batchResponse.Resultado = "E";
                        batchResponse.CodigoError = "Equivalencias";
                        batchResponse.MensajeError = "No se encontró equivalencia con AFIP. Campos: " + strEquivalenciaErrorFields;
                    }
                }

                //Armar info de los documentos
                if (feResponse.FeDetResp != null)
                {
                    for (int i = 0; i < feResponse.FeDetResp.Length; i++)
                    {
                        ResponseHeader thisHeader = new ResponseHeader();
                        if (feResponse.FeDetResp[i].CAE == "NULL")
                            feResponse.FeDetResp[i].CAE = "";
                        thisHeader.CAE = feResponse.FeDetResp[i].CAE;
                        thisHeader.CodigoDocumentoComprador = feResponse.FeDetResp[i].DocTipo.ToString();
                        thisHeader.NroDocumentoComprador = feResponse.FeDetResp[i].DocNro.ToString();
                        thisHeader.TipoComprobante = feResponse.FeCabResp.CbteTipo.ToString();
                        thisHeader.NroComprobanteDesde = feResponse.FeDetResp[i].CbteDesde.ToString();
                        thisHeader.NroComprobanteHasta = feResponse.FeDetResp[i].CbteHasta.ToString();
                        thisHeader.Importe = loteDocs.RequestHeaders[i].Importe;
                        thisHeader.ImporteNoGravado = loteDocs.RequestHeaders[i].ImporteNoGravado;
                        thisHeader.ImporteGravado = loteDocs.RequestHeaders[i].ImporteGravado;
                        thisHeader.ImporteImpuestoLiquidado = loteDocs.RequestHeaders[i].ImporteImpuestoLiquidado;
                        thisHeader.ImporteRNI_Percepcion = loteDocs.RequestHeaders[i].ImporteRNI_Percepcion;
                        thisHeader.ImporteExento = loteDocs.RequestHeaders[i].ImporteExento;
                        thisHeader.Resultado = feResponse.FeDetResp[i].Resultado;

                        thisHeader.FechaComprobante = feResponse.FeDetResp[i].CbteFch;
                        thisHeader.FechaVencimiento = feResponse.FeDetResp[i].CAEFchVto;

                        thisHeader.PuntoVenta = loteDocs.RequestHeaders[i].PuntoVenta;
                        thisHeader.LetraComprobante = loteDocs.RequestHeaders[i].LetraComprobante;
                        thisHeader.NroInternoERP = loteDocs.RequestHeaders[i].NroInternoERP;
                        thisHeader.SQLID = loteDocs.RequestHeaders[i].SQLID;

                        wsfe.FERecuperaLastCbteResponse feLastCMPRespose = afipFE.FERecuperaUltimoComprobante(thisHeader.TipoComprobante, thisHeader.PuntoVenta);
                        thisHeader.UltimoNroComprobanteUsado = feLastCMPRespose.CbteNro.ToString();

                        if (feResponse.Errors != null && feResponse.Errors.Length > 0 && feResponse.Errors[0] != null)
                        {
                            thisHeader.Motivo = feResponse.Errors[0].Code.ToString();
                            thisHeader.MotivoDescripcion = feResponse.Errors[0].Msg;

                            if (thisHeader.Motivo == "10016")
                                thisHeader.MotivoDescripcion += " UltimoNroComprobanteUsado: " + thisHeader.UltimoNroComprobanteUsado;
                        }

                        //NUEVO DESDE VERSION 1 DE AFIP
                        if (feResponse.FeDetResp[i].Observaciones != null)
                        {
                            foreach (wsfe.Obs wsObs in feResponse.FeDetResp[i].Observaciones)
                            {
                                ResponseHeaderObs resObs = new ResponseHeaderObs();

                                resObs.Codigo = wsObs.Code.ToString();
                                resObs.Msg = wsObs.Msg;

                                if (resObs.Codigo == "10016")
                                    resObs.Msg += " UltimoNroComprobanteUsado: " + thisHeader.UltimoNroComprobanteUsado;

                                thisHeader.Observaciones.Add(resObs);
                            }
                        }

                        thisHeader.FechaDesdeServicioFacturado = feResponse.FeDetResp[i].CbteDesde.ToString();
                        thisHeader.FechaHastaServicioFacturado = feResponse.FeDetResp[i].CbteHasta.ToString();
                        thisHeader.FechaVencimientoPago = loteDocs.RequestHeaders[i].FechaVencimientoPago;

                        batchResponse.ResponseHeaders.Add(thisHeader);
                    }
                }
                else
                {
                    for (int i = 0; i < loteDocs.RequestHeaders.Count; i++)
                    {
                        ResponseHeader thisHeader = new ResponseHeader();

                        thisHeader.CAE = "";
                        thisHeader.TipoComprobante = loteDocs.RequestHeaders[i].TipoComprobante;
                        thisHeader.PuntoVenta = loteDocs.RequestHeaders[i].PuntoVenta;
                        thisHeader.NroComprobanteDesde = loteDocs.RequestHeaders[i].NroComprobanteDesde;
                        thisHeader.NroComprobanteHasta = loteDocs.RequestHeaders[i].NroComprobanteHasta;
                        thisHeader.Importe = loteDocs.RequestHeaders[i].Importe;
                        thisHeader.ImporteNoGravado = loteDocs.RequestHeaders[i].ImporteNoGravado;
                        thisHeader.ImporteGravado = loteDocs.RequestHeaders[i].ImporteGravado;
                        thisHeader.ImporteImpuestoLiquidado = loteDocs.RequestHeaders[i].ImporteImpuestoLiquidado;
                        thisHeader.ImporteRNI_Percepcion = loteDocs.RequestHeaders[i].ImporteRNI_Percepcion;
                        thisHeader.ImporteExento = loteDocs.RequestHeaders[i].ImporteExento;
                        thisHeader.FechaComprobante = loteDocs.RequestHeaders[i].FechaComprobante;
                        thisHeader.Motivo = batchResponse.CodigoError;
                        thisHeader.MotivoDescripcion = batchResponse.MensajeError;
                        thisHeader.FechaDesdeServicioFacturado = loteDocs.RequestHeaders[i].FechaDesdeServicioFacturado;
                        thisHeader.FechaHastaServicioFacturado = loteDocs.RequestHeaders[i].FechaHastaServicioFacturado;
                        thisHeader.FechaVencimientoPago = loteDocs.RequestHeaders[i].FechaVencimientoPago;
                        thisHeader.NroInternoERP = loteDocs.RequestHeaders[i].NroInternoERP;
                        thisHeader.LetraComprobante = loteDocs.RequestHeaders[i].LetraComprobante;
                        thisHeader.SQLID = loteDocs.RequestHeaders[i].SQLID;

                        batchResponse.ResponseHeaders.Add(thisHeader);
                    }
                }

                //DEBUG LINE
                if (Convert.ToBoolean(oSettings.ActivarDebug))
                    Utils.Utils.DebugLine(Utils.Utils.SerializeObject(batchResponse), oSettings.PathDebug + "\\" + SQLID + "-P4.ResponseBatch-" + DateTime.Now.Hour.ToString("00") + DateTime.Now.Minute.ToString("00") + DateTime.Now.Second.ToString("00") + DateTime.Now.Millisecond.ToString("000") + ".xml");

                #endregion

                #region Registrar Fin

                //TODO: VERIFICAR ESTA PARTE CAPTURA MAL LOS ERRORES
                switch (batchResponse.Resultado)
                {
                    case "A":
                        estadoDocumento = "Aceptado";
                        cae = batchResponse.ResponseHeaders[0].CAE;
                        FechaVencimiento = batchResponse.ResponseHeaders[0].FechaVencimiento;

                        break;
                    case "R":
                        estadoDocumento = "Rechazado";
                        cae = "";
                        FechaVencimiento = "";
                        break;

                    default:
                        if (batchResponse.Reproceso.ToLower() == "s")
                        {
                            estadoDocumento = "Rechazado";
                            cae = batchResponse.ResponseHeaders[0].CAE;
                            FechaVencimiento = batchResponse.ResponseHeaders[0].FechaVencimiento;
                        }
                        else
                        {
                            estadoDocumento = "Error";
                            cae = "";
                            FechaVencimiento = "";
                        }
                        break;
                }

                try
                {
                    sqlEngine.LogBatchEnd(SQLID, estadoDocumento, cae, FechaVencimiento);
                }
                catch (Exception ex)
                {
                    sqlEngine.LogError(SQLID, "0", "Respuesta Recibida", "Error: " + ex.Message);
                }

                #endregion
            }

            return batchResponse.GetXMLString();
        }
예제 #2
0
파일: AfipFE.cs 프로젝트: javierlov/FE
        public wsfe.FECAEResponse FEAuthRequest(RequestBatch docBatch, Settings oSettings)
        {
            wsfe.FECAECabRequest objFECabeceraRequest = new wsfe.FECAECabRequest();
            wsfe.FECAEDetRequest objFEDetalleRequest = new wsfe.FECAEDetRequest();
            wsfe.FECAERequest objFERequest = new wsfe.FECAERequest();
            wsfe.FECAEResponse objFEResponse = new wsfe.FECAEResponse();
            wsfe.AlicIva objIva = null;
            wsfe.Tributo objTributo = null;

            DBEngine.SQLEngine sqlEngine = new FacturaElectronica.DBEngine.SQLEngine();

            int i = 0;
            int iIvaItems = 0;
            int iTributosItems = 0;

            try
            {
                objFECabeceraRequest.CantReg = Convert.ToInt16(docBatch.CantidadComprobantes);
                objFECabeceraRequest.PtoVta = Convert.ToInt16(docBatch.RequestHeaders[0].PuntoVenta);
                objFECabeceraRequest.CbteTipo = Convert.ToInt16(docBatch.RequestHeaders[0].TipoComprobante);

                wsfe.FECAEDetRequest[] aObjFEDetalleRequest = new wsfe.FECAEDetRequest[Convert.ToInt16(objFECabeceraRequest.CantReg)];

                int arrayIndex = 0;
                for (i = 0; i < objFECabeceraRequest.CantReg; i++)
                {
                    objFEDetalleRequest = new wsfe.FECAEDetRequest();

                    //Si el numero de documento viene vacio asumo que es un consumidor final 99
                    if (docBatch.RequestHeaders[i].CompradorNroDocumento == string.Empty)
                    {
                        docBatch.RequestHeaders[i].CompradorCodigoDocumento = "99";
                        docBatch.RequestHeaders[i].CompradorNroDocumento = "0";
                    }

                    objFEDetalleRequest.DocTipo = Convert.ToInt16(docBatch.RequestHeaders[i].CompradorCodigoDocumento);
                    objFEDetalleRequest.DocNro = (long)Convert.ToDouble(docBatch.RequestHeaders[i].CompradorNroDocumento);

                    objFEDetalleRequest.CbteDesde = (long)Convert.ToDouble(docBatch.RequestHeaders[i].NroComprobanteDesde);
                    objFEDetalleRequest.CbteHasta = (long)Convert.ToDouble(docBatch.RequestHeaders[i].NroComprobanteHasta);
                    objFEDetalleRequest.ImpTotal = Convert.ToDouble(docBatch.RequestHeaders[i].Importe);
                    objFEDetalleRequest.ImpTotConc = Convert.ToDouble(docBatch.RequestHeaders[i].ImporteNoGravado);
                    objFEDetalleRequest.ImpNeto = Convert.ToDouble(docBatch.RequestHeaders[i].ImporteGravado);
                    //objFEDetalleRequest.impto_liq_rni = Convert.ToDouble(docBatch.RequestHeaders[i].ImporteRNI_Percepcion);????
                    //objFEDetalleRequest.ImpIVA = Convert.ToDouble(docBatch.RequestHeaders[i].ImporteImpuestoLiquidado);

                    objFEDetalleRequest.ImpOpEx = Convert.ToDouble(docBatch.RequestHeaders[i].ImporteExento);

                    //Agrego todas las alicuotas en array
                    //1 No gravado
                    //2 Exento
                    //3 0%
                    //4 10.5%
                    //5 21%
                    //6 27%
                    if (docBatch.RequestHeaders[i].RequestAlicuotas.Count > 0)
                    {
                        objFEDetalleRequest.Iva = new wsfe.AlicIva[docBatch.RequestHeaders[i].RequestAlicuotas.Count];
                        iIvaItems = 0;
                        foreach (RequestAlicuota alic in docBatch.RequestHeaders[i].RequestAlicuotas)
                        {
                            if (alic != null)
                            {
                                objIva = new wsfe.AlicIva();
                                objIva.Id = Convert.ToInt32(alic.Id);
                                objIva.BaseImp = Convert.ToDouble(String.Format("{0:0.00}", alic.BaseImp));
                                objIva.Importe = Convert.ToDouble(String.Format("{0:0.00}", alic.Importe));

                                objFEDetalleRequest.Iva[iIvaItems] = objIva;

                                iIvaItems++;

                                //Agrego importe al total de alicuotas de IVA
                                objFEDetalleRequest.ImpIVA += objIva.Importe;
                            }
                        }
                    }
                    objFEDetalleRequest.ImpIVA = Convert.ToDouble(String.Format("{0:0.00}", objFEDetalleRequest.ImpIVA));

                    //Agrego todos los tributos en array
                    //1	Impuestos nacionales
                    //2	Impuestos provinciales
                    //3	Impuestos municipales
                    //4	Impuestos internos
                    //99 Otros
                    if (docBatch.RequestHeaders[i].RequestTributos.Count > 0)
                    {
                        objFEDetalleRequest.Tributos = new wsfe.Tributo[docBatch.RequestHeaders[i].RequestTributos.Count];
                        iTributosItems = 0;
                        foreach (RequestTributo trib in docBatch.RequestHeaders[i].RequestTributos)
                        {
                            if (trib != null)
                            {
                                objTributo = new wsfe.Tributo();
                                objTributo.Id = Convert.ToInt16(trib.Id);
                                objTributo.BaseImp = Convert.ToDouble(String.Format("{0:0.00}", trib.BaseImp));
                                objTributo.Importe = Convert.ToDouble(String.Format("{0:0.00}", trib.Importe));
                                objTributo.Alic = Convert.ToDouble(String.Format("{0:#,##0.00}", trib.Alic));

                                objFEDetalleRequest.Tributos[iTributosItems] = objTributo;

                                iTributosItems++;

                                //Agrego importe al total de tributos
                                objFEDetalleRequest.ImpTrib += objTributo.Importe;
                            }
                        }
                    }

                    // Las fechas deben venir en formato "YYYY-MM-DD"
                    objFEDetalleRequest.CbteFch = Convert.ToDateTime(docBatch.RequestHeaders[i].FechaComprobante).ToString("yyyyMMdd");

                    //Es 1 si son productos 2 servicios, 3 productos y servicios
                    if (docBatch.SonServicios == "1")
                        objFEDetalleRequest.Concepto = 3;
                    else
                        objFEDetalleRequest.Concepto = 1;

                    if (objFEDetalleRequest.Concepto == 3)
                    {
                        objFEDetalleRequest.FchServDesde = Convert.ToDateTime(docBatch.RequestHeaders[i].FechaDesdeServicioFacturado).ToString("yyyyMMdd");
                        objFEDetalleRequest.FchServHasta = Convert.ToDateTime(docBatch.RequestHeaders[i].FechaHastaServicioFacturado).ToString("yyyyMMdd");
                        objFEDetalleRequest.FchVtoPago = Convert.ToDateTime(docBatch.RequestHeaders[i].FechaVencimientoPago).ToString("yyyyMMdd");
                    }

                    objFEDetalleRequest.MonId = docBatch.RequestHeaders[i].CodigoMoneda;
                    objFEDetalleRequest.MonCotiz = 1;

                    aObjFEDetalleRequest[arrayIndex] = objFEDetalleRequest;
                    arrayIndex += 1;
                }

                objFERequest.FeCabReq = objFECabeceraRequest;
                objFERequest.FeDetReq = aObjFEDetalleRequest;

                //DEBUG LINE
                if (Convert.ToBoolean(oSettings.ActivarDebug))
                    Utils.Utils.DebugLine(Utils.Utils.SerializeObject(objFERequest), oSettings.PathDebug + "\\" + docBatch.RequestHeaders[0].SQLID + "-P2.FERequest-" + DateTime.Now.Hour.ToString("00") + DateTime.Now.Minute.ToString("00") + DateTime.Now.Second.ToString("00") + DateTime.Now.Millisecond.ToString("000") + ".xml");

                objFEResponse = feService.FECAESolicitar(objFEAuthRequest, objFERequest);
            }
            catch (Exception ex)
            {
                int iElement = 0;
                if(i > 0)
                    iElement = i - 1;
                else
                    iElement = 0;

                objFEResponse.Errors = new wsfe.Err[1];
                objFEResponse.Errors[0] = new wsfe.Err();
                objFEResponse.Errors[0].Code = 668;
                objFEResponse.Errors[0].Msg = ex.Message;

                string url = oSettings.UrlFEWebService;
                sqlEngine.LogError(docBatch.RequestHeaders[iElement].SQLID, "0", "Autorización", "Error no conocido: (AfipFE) " + ex.Message);
            }

            return objFEResponse;
        }