public static BaseResponse ProcessBill(ref BillEntity pBill, CreditOrDebitNoteEntity pDocumentReference) { BaseResponse vResponse = new BaseResponse { IsSuccessful = false }; pBill.Status = BillStatus.Error.ToString(); try { var vServicioBLL = new ServicioBLL(); var vDocumentoEncabezado = new DocumentoEncabezado(); var vUsuarioHacienda = new UsuarioHacienda(); var vListaMedioPago = new List <DocumentoMedioPago>(); var vDetalleDocumento = new List <DocumentoDetalle>(); //Encabezado vDocumentoEncabezado.Clave = pBill.DocumentKey; vDocumentoEncabezado.TipoCambio = 1.00; vDocumentoEncabezado.Fecha = DateTime.Now; vDocumentoEncabezado.Moneda = "CRC"; vDocumentoEncabezado.CondicionVenta = pBill.SellCondition; vDocumentoEncabezado.PlazoCredito = string.IsNullOrEmpty(pBill.CreditTerm)?"0": pBill.CreditTerm; vDocumentoEncabezado.NormativaFechaResolucion = "20-02-2017 13:22:22"; vDocumentoEncabezado.NormativaNumeroResolucion = "DGT-R-48-2016"; vDocumentoEncabezado.Observacion = string.IsNullOrEmpty(pBill.Observation) ? string.Empty: pBill.Observation; vDocumentoEncabezado.SubTotal = Convert.ToDouble(pBill.SubTotalProducts); vDocumentoEncabezado.Descuento = Convert.ToDouble(pBill.DiscountAmount); vDocumentoEncabezado.Impuesto = Convert.ToDouble(pBill.TaxesToPay); vDocumentoEncabezado.DocumentoConsecutivo = pBill.ConsecutiveNumber + ""; //Emisor vDocumentoEncabezado.Emisor.Identificacion = pBill.User.UserLegalNumber; vDocumentoEncabezado.Emisor.IdentificacionTipo = pBill.User.IdentificationType; vDocumentoEncabezado.Emisor.Direccion = pBill.User.LocationDescription; vDocumentoEncabezado.Emisor.CodigoPais = "506"; vDocumentoEncabezado.Emisor.Provincia = pBill.User.ProvinciaCode; vDocumentoEncabezado.Emisor.Canton = pBill.User.CantonCode; vDocumentoEncabezado.Emisor.Distrito = pBill.User.DistritoCode; vDocumentoEncabezado.Emisor.Barrio = pBill.User.BarrioCode; vDocumentoEncabezado.Emisor.Nombre = pBill.User.Name; vDocumentoEncabezado.Emisor.NombreComercial = string.IsNullOrEmpty(pBill.User.ComercialName)? string.Empty: pBill.User.ComercialName; vDocumentoEncabezado.Emisor.Telefono = pBill.User.PhoneNumber; vDocumentoEncabezado.Emisor.Fax = "00000000"; vDocumentoEncabezado.Emisor.Email = pBill.User.Email; //Receptor vDocumentoEncabezado.Receptor.IdentificacionExtranjero = pBill.Client.ForeignIdentification; vDocumentoEncabezado.Receptor.Identificacion = pBill.Client.ClientLegalNumber; vDocumentoEncabezado.Receptor.IdentificacionTipo = pBill.Client.IdentificationType; vDocumentoEncabezado.Receptor.Direccion = pBill.Client.LocationDescription; vDocumentoEncabezado.Receptor.CodigoPais = "506"; vDocumentoEncabezado.Receptor.Provincia = pBill.Client.ProvinciaCode; vDocumentoEncabezado.Receptor.Canton = pBill.Client.CantonCode; vDocumentoEncabezado.Receptor.Distrito = pBill.Client.DistritoCode; vDocumentoEncabezado.Receptor.Barrio = pBill.Client.BarrioCode; vDocumentoEncabezado.Receptor.Nombre = pBill.Client.Name; vDocumentoEncabezado.Receptor.NombreComercial = pBill.Client.ComercialName; vDocumentoEncabezado.Receptor.Telefono = pBill.Client.PhoneNumber; vDocumentoEncabezado.Receptor.Fax = "00000000"; vDocumentoEncabezado.Receptor.Email = pBill.Client.Email; //Medio de Pago var vMedioDePago = new DocumentoMedioPago(); vMedioDePago.Codigo = pBill.PaymentMethod; vListaMedioPago.Add(vMedioDePago); vDocumentoEncabezado.MedioPago = vListaMedioPago; var vListaProductos = JsonConvert.DeserializeObject <Client>(pBill.SoldProductsJSON); foreach (var vProducto in vListaProductos.ClientProducts) { if (vProducto.ProductQuantity > 0) { //Detalle del Producto decimal vProductTotal = vProducto.Price * vProducto.ProductQuantity; var vLinea = new DocumentoDetalle(); vLinea.Cantidad = vProducto.ProductQuantity; vLinea.Nombre = vProducto.Name; vLinea.Descripcion = vProducto.Description; vLinea.Codigo = vProducto.ProductCode; vLinea.Tipo = vProducto.ProductType; vLinea.Unidad = vProducto.MeasurementUnit; vLinea.UnidadMedidaComercial = string.IsNullOrEmpty(vProducto.MeasurementUnitType)?string.Empty: vProducto.MeasurementUnitType; vLinea.EsProducto = true; vLinea.Precio = Convert.ToDouble(vProducto.Price); vLinea.Descuento = Convert.ToDouble((vProductTotal / 100) * pBill.Client.DefaultDiscountPercentage); vLinea.DescuentoDescripcion = string.IsNullOrEmpty(pBill.DiscountNature) ? string.Empty : pBill.DiscountNature; if (pBill.Client.DefaultTaxesPercentage > 0) { // Impuestos var vLineaListaImpuesto = new List <DocumentoDetalleImpuesto>(); var vLineaImpuesto = new DocumentoDetalleImpuesto(); vLineaImpuesto.Tipo = pBill.TaxCode; vLineaImpuesto.Tarifa = Convert.ToDouble(pBill.Client.DefaultTaxesPercentage); vLineaImpuesto.Monto = Convert.ToDouble(((vProductTotal - Convert.ToDecimal(vLinea.Descuento)) / 100) * pBill.Client.DefaultTaxesPercentage); vLineaListaImpuesto.Add(vLineaImpuesto); // Se agrega el impuesto a Lista vLinea.DocumentoDetalleImpuesto = vLineaListaImpuesto; } // Se agrega el Producto completo a todos los demas vDetalleDocumento.Add(vLinea); } else { // El producto no tiene ninguna cantidad a facturar } } //Se agrega referencia si es que existe if (pDocumentReference != null) { var vReferenceList = new List <DocumentoReferencia>(); var vReferenceDoc = new DocumentoReferencia(); vReferenceDoc.Codigo = pDocumentReference.ReferenceCode; vReferenceDoc.FechaEmision = pDocumentReference.EmissionDate; vReferenceDoc.Numero = pDocumentReference.DocuementKey; vReferenceDoc.Razon = pDocumentReference.ReasonDescription; vReferenceDoc.TipoDoc = HaciendaTransactionType.Factura_Electronica; vReferenceList.Add(vReferenceDoc); vDocumentoEncabezado.Referencia = vReferenceList; } // Se agrega el Segmento de todos los productos vDocumentoEncabezado.DocumentoDetalle = vDetalleDocumento; // Datos de Hacienda vUsuarioHacienda.username = pBill.Client.User.HaciendaUsername; vUsuarioHacienda.password = pBill.Client.User.HaciendaPassword; vUsuarioHacienda.Pin = pBill.Client.User.HaciendaCryptographicPIN; vUsuarioHacienda.Certificado = pBill.Client.User.HaciendaCryptographicFile; vUsuarioHacienda.modalidadProduccion = false; vUsuarioHacienda.urlhaciendaAuthApiDesarrollo = UrlhaciendaAuthApiDesarrollo; vUsuarioHacienda.urlhaciendaAuthApiProduccion = UrlhaciendaAuthApiProduccion; vUsuarioHacienda.urlhaciendaApiDesarrollo = UrlhaciendaApiDesarrollo; vUsuarioHacienda.urlhaciendaApiProduccion = UrlhaciendaApiProduccion; var vReply = vServicioBLL.fGenerarDocumento(vDocumentoEncabezado, vUsuarioHacienda, MaxRetryCount); if (vReply != null) { // try to save the Sended XML always if (!string.IsNullOrEmpty(vReply.xmlDocumento)) { pBill.XMLSendedToHacienda = vReply.xmlDocumento; } if (!string.IsNullOrEmpty(vReply.xmlRespuesta)) { Regex vRegex = new Regex("<DetalleMensaje>(.+)</DetalleMensaje>"); string msgWithoutChangeLines = Regex.Replace(vReply.xmlRespuesta, "\r\n?|\n", ""); var vMatch = vRegex.Match(msgWithoutChangeLines); if (vMatch.Success) { pBill.SystemMesagges = vReply.estado + "-" + vReply.msg + vMatch.Value; } else { pBill.SystemMesagges = vReply.estado + "-" + vReply.msg; } } else { pBill.SystemMesagges = vReply.estado + "-" + vReply.msg + string.Format("| REASON GET: {0} | REASON POST: {1}", vReply.reasonPhraseGETHacienda, vReply.reasonPhrasePOSTHacienda); } if (vReply.ok) { if (!string.IsNullOrEmpty(vReply.xmlRespuesta)) { pBill.XMLReceivedFromHacienda = vReply.xmlRespuesta; } switch (vReply.estado) { case BillStatusHacienda.Aceptada: pBill.Status = BillStatus.Done.ToString(); vResponse.IsSuccessful = true; break; case BillStatusHacienda.Rechazada: pBill.Status = BillStatus.Rejected.ToString(); vResponse.IsSuccessful = false; break; case BillStatusHacienda.Procesando: pBill.Status = BillStatus.Processing.ToString(); vResponse.IsSuccessful = false; break; default: pBill.Status = BillStatus.Error.ToString(); vResponse.IsSuccessful = false; break; } if (string.IsNullOrEmpty(pBill.SystemMesagges)) { pBill.SystemMesagges = pBill.Status + vReply.msg; } vResponse.UserMessage = pBill.SystemMesagges; } else { if (string.IsNullOrEmpty(pBill.Status)) { pBill.Status = BillStatus.Error.ToString(); } if (string.IsNullOrEmpty(pBill.SystemMesagges)) { pBill.SystemMesagges = "Error." + "La respuesta no fue positiva:" + vReply.msg; } if (string.IsNullOrEmpty(vReply.statusCodePOSTHacienda) || !vReply.statusCodePOSTHacienda.Equals(AcceptedHTTPCode)) { if (!string.IsNullOrEmpty(vReply.msg) && vReply.msg.Contains("ya fue recibido anteriormente")) { pBill.Status = BillStatus.Processing.ToString(); } else { pBill.Status = BillStatus.Error.ToString(); } } else { pBill.Status = BillStatus.Processing.ToString(); } pBill.ReasonPhraseGETHacienda = vReply.reasonPhraseGETHacienda; pBill.ReasonPhrasePOSTHacienda = vReply.reasonPhrasePOSTHacienda; pBill.StatusCodeGETHacienda = vReply.statusCodeGETHacienda; pBill.StatusCodePOSTHacienda = vReply.statusCodePOSTHacienda; vResponse.IsSuccessful = false; vResponse.UserMessage = pBill.SystemMesagges; } } else { pBill.SystemMesagges = "No se recibio respuesta de hacienda"; vResponse.UserMessage = "Error." + "No se recibio respuesta de hacienda"; pBill.Status = BillStatus.Error.ToString(); } pBill.HaciendaFailCounter++; } catch (Exception ex) { vResponse.UserMessage = ex.Message; vResponse.TechnicalMessage = ex.ToString(); vResponse.IsSuccessful = false; } return(vResponse); }