2 using System.Collections.Generic;
9 using Sage.
ES.Batuz.Entities;
10 using Sage.
ES.Batuz.Entities.ComModel._240.Annulation;
11 using Sage.
ES.Batuz.Entities.ComModel._240.Common;
12 using Sage.
ES.Batuz.Entities.ComModel._240.Invoice;
13 using Sage.
ES.Batuz.Interfaces.Entities;
25 namespace sage.addons.factucert.
Negocio.ModelosFiscalLibros
29 private Process _process = null;
31 private ModeloEnum model;
32 private bool generadoXML =
true;
33 private bool enviadoXML =
true;
35 private List<RespuestaFacturaBase> respuestas =
new List<RespuestaFacturaBase>();
36 private string processMsgError =
"";
37 private bool _lEsLibroBienes140 =
false;
39 protected string tag_Envio_Ticketbai = FUNCTIONS.LeerConfigIni(
"[ENVIO_TICKETBAI]");
45 _ModeloFiscal = modelo;
49 public override bool _GenerarXML(
ILibro libro,
bool isSend, Dictionary<string, object> parametros)
57 model = ModeloEnum.Modelo_140;
60 model = ModeloEnum.Modelo_240;
64 if (parametros.Count < 1)
69 if (this._process == null)
71 this._process =
new Process();
76 IConfig config =
new Config();
77 config.TraceAdditionalInfo =
"{date} | pid:{pid} | t:{tid} | {assembly}";
78 config.TraceConfigFile =
"";
79 config.TraceFile = _RutaLog +
"\\" + (
string.IsNullOrWhiteSpace(_Libro.
_Libro) ?
"Libro" : _Libro.
_Libro.Trim());
82 if (!Directory.Exists(config.TraceFile))
84 Directory.CreateDirectory(config.TraceFile);
90 DB.Registrar_Error(e);
91 config.TraceFile =
"";
94 config.TraceHeaderSeparator =
"";
95 config.TraceMaxArchivedFiles =
"7";
96 config.TraceMode =
"All";
97 config.TracePatternDateTime =
"{LOCAL}dd/MM/yyyy HH:mm:ss.fff";
98 config.TraceRollSizeKB =
"10000";
100 config.Certificate = FACTUCERT._FactuCertConfig._ConfigFactuCertModelo._CNom;
101 config.CertificateThumbprint =
"";
103 config.VersionXAd =
Sage.
ES.Batuz.Interfaces.Entities.VersionXAd.ver_EPES;
104 config.CertificateStore =
Sage.
ES.Batuz.Interfaces.Entities.CertificateStore.cert_MY;
105 _process.Config = config;
107 foreach (KeyValuePair<string, object> item
in parametros)
109 if (item.Key.Contains(
"Libro") && item.Value != null)
111 string cDate = DateTime.Now.ToString(
"yyyyMMdd_hhmmss");
112 if (item.Value is List<object>)
114 List<object> lItemValue = (List<object>)item.Value;
116 for (
int nInd = 0; nInd < lItemValue.Count; nInd++)
118 tipoEnvioModelos = convertirTipoOperacionLibroEnTipoEnvioModelos((
TipoOperacionLibro)(((dynamic)lItemValue[nInd]).Cabecera.Operacion));
119 if (_lEsLibroBienes140)
120 subcapituloBien = convertirSubcapituloEnSubcapituloBien(Convert.ToString((((dynamic)item.Value).Cabecera.Subcapitulo)));
121 string cContador = (nInd + 1).ToString(
"000");
122 string cIdentificador = cDate + (
string.IsNullOrWhiteSpace(cContador) ?
"" :
"_" + cContador);
123 GenerarEnviarXML(isSend, config, lItemValue[nInd], tipoEnvioModelos.ToString(), cIdentificador);
129 tipoEnvioModelos = convertirTipoOperacionLibroEnTipoEnvioModelos((
TipoOperacionLibro)(((dynamic)item.Value).Cabecera.Operacion));
130 if (_lEsLibroBienes140)
131 subcapituloBien = convertirSubcapituloEnSubcapituloBien(Convert.ToString((((dynamic)item.Value).Cabecera.Subcapitulo)));
133 GenerarEnviarXML(isSend, config, item.Value, tipoEnvioModelos.ToString(), cDate);
138 if (this._process != null && isSend && _Resultado.Count == 0 && respuestas.Count == 0)
144 ProcesarResultados(isSend);
146 catch (Exception loEx)
148 string lcMensaje = loEx.Message;
161 private void Entorno(
ILibro toLibro)
164 _cHost =
"https://pruesarrerak.bizkaia.eus/N3B4000M/aurkezpena";
166 _cHost =
"https://sarrerak.bizkaia.eus/N3B4000M/aurkezpena";
176 switch (tipoOperacionLibro)
195 return tipoEnvioModelos;
203 SubcapituloBien convertirSubcapituloEnSubcapituloBien(
string tcSubcapituloBien140)
206 string lcSub140 = tcSubcapituloBien140.ToLower().Trim();
210 case "alta_bienes_afectos_o_inversion":
214 case "regularizacion_anual_bienes_inversion":
218 case "baja_bienes_afectos_o_inversión":
236 private string _cHost = $
"https://pruesarrerak.bizkaia.eus/N3B4000M/aurkezpen";
238 private void GenerarEnviarXML(
bool isSend, IConfig config,
object libro,
string key,
string cIdentificador)
240 string rutaFichero = _RutaFicheroXML +
"\\" + (
string.IsNullOrWhiteSpace(_Libro.
_Libro) ?
"Libro" : _Libro.
_Libro.Trim());
243 if (!Directory.Exists(rutaFichero))
245 Directory.CreateDirectory(rutaFichero);
251 DB.Registrar_Error(e);
254 rutaFichero = rutaFichero +
"\\" + cIdentificador +
"_" + key.ToLower().Replace(
"libro",
"").Trim() +
".xml";
256 if (this._process != null)
258 ProcesoGenerar(config, libro, rutaFichero, isSend, key, cIdentificador);
279 private void ParseError(ref
string[] taErrorSplit)
281 if (taErrorSplit.Length < 2)
284 int lnIndice = taErrorSplit.Length - 1;
286 string lcError = taErrorSplit[lnIndice].ToUpper().Trim();
288 if (lcError ==
"EMPTY")
290 string lcCodigo = taErrorSplit[lnIndice - 1].Trim();
292 taErrorSplit[lnIndice] = $
"Se ha detectado un problema al enviar información. Puede tratarse de una demora en la conexión o comportamiento inesperado de la solicitud." +
293 (!
string.IsNullOrWhiteSpace(lcCodigo) ? $
" Código: {lcCodigo} ." :
"");
297 if ((lcError.Contains(
"CONEXIÓN") && (lcError.Contains(
"SERVIDOR") || lcError.Contains(
"INESPERADA"))) ||
298 (lcError.Contains(
"EXCEDIÓ") && lcError.Contains(
"OPERACIÓN")) ||
299 (lcError.Contains(
"ANULADA") && lcError.Contains(
"SOLICITUD")))
306 private void ProcesoGenerar(IConfig config,
object libro,
string rutaFichero,
bool isSend,
string key,
string cIdentificador)
308 this._process.Model = model;
309 this._process.TypeBook = libro;
310 this._process.OutputFileName = rutaFichero;
311 config.SendFact =
new SendFact();
312 config.SendFact.XmlFact = rutaFichero;
313 config.EnvioDiferido = !isSend;
314 config.SendFact.Host = config.SendFact.Host = _cHost;
316 generadoXML = this._process.GenerateCom();
317 processMsgError =
"";
321 processMsgError = (_process != null && !
string.IsNullOrWhiteSpace(_process.MsgError) ? _process.MsgError :
"");
327 processMsgError =
"";
331 string listaFacturas =
"";
332 List<ILibroFila> lolstSel = _Libro.
_Filas.Where(f => f._Seleccion && (f._ProximoEnvio == tipoEnvioModelos || f._ProximoEnvio ==
TipoEnvioModelos.Nada)).ToList();
335 listaFacturas += fila.
_Factura +
";";
338 string lcLog =
string.Format(
"\r\nModelo --> {0} \r\nNombre del libro --> {1}_{3} \r\nRuta XML --> {5} \r\nFacturas --> {2} \r\nRespuesta --> {4}", _ModeloFiscal.
_Modelo, _Libro.
_Libro.Trim(), listaFacturas, key, processMsgError, rutaFichero);
340 factucert.Log(ew.enumerations.TipoMensaje.Info, lcLog,
"_Envio Modelo_" + _ModeloFiscal.
_Modelo +
"_" + key +
"_" + cIdentificador);
342 enviadoXML = generadoXML & isSend;
344 string codigoError =
"";
345 Dictionary<string[], string[]> allDes_Error =
new Dictionary<string[], string[]>();
347 if (!
string.IsNullOrWhiteSpace(processMsgError))
349 allDes_Error = extraerDescripcionesdeErrores(processMsgError, out codigoError);
353 string[] clave = {
"",
"" };
354 string[] value = {
"",
"" };
355 allDes_Error.Add(clave, value);
359 foreach (KeyValuePair<
string[],
string[]> des_Error
in allDes_Error)
362 if (
string.IsNullOrWhiteSpace(des_Error.Key[1]))
371 List<RespuestaFacturaBase> itemsRespuestas = crearRespuestas(codigoError, des_Error, estado, rutaFichero);
374 respuestas.Add(item);
385 private void ProcesoEnviar(IConfig config,
object libro,
string rutaFichero,
string key,
string cIdentificador)
388 if (
String.IsNullOrWhiteSpace(tag_Envio_Ticketbai))
390 this._process.Model = model;
394 this._process.TypeBook = libro;
396 catch (Exception loEx)
398 string lcMensaje = loEx.Message;
402 config.SendFact =
new SendFact();
403 config.SendFact.XmlFact = rutaFichero;
404 config.EnvioDiferido =
true;
405 config.SendFact.Host = _cHost;
411 enviadoXML = this._process.Send();
413 catch (Exception loEx)
415 string lcMensaje = loEx.Message;
419 string codigoError =
"";
420 processMsgError =
"";
423 processMsgError = (_process != null && !
string.IsNullOrWhiteSpace(_process.MsgError) ? _process.MsgError :
"");
429 processMsgError =
"";
431 string listaFacturas =
"";
432 List<ILibroFila> lolstSel = _Libro.
_Filas.Where(f => f._Seleccion && (f._ProximoEnvio == tipoEnvioModelos || f._ProximoEnvio ==
TipoEnvioModelos.Nada)).ToList();
435 listaFacturas += fila.
_Factura +
";";
438 string lcLog =
string.Format(
"\r\nModelo --> {0} \r\nNombre del libro --> {1}_{3} \r\nRuta XML --> {5} \r\nFacturas --> {2} \r\nRespuesta --> {4}", _ModeloFiscal.
_Modelo, _Libro.
_Libro.Trim(), listaFacturas, key, processMsgError, rutaFichero);
440 factucert.Log(ew.enumerations.TipoMensaje.Info, lcLog,
"_Envio Modelo_" + _ModeloFiscal.
_Modelo +
"_" + key +
"_" + cIdentificador);
445 Dictionary<string[], string[]> allDes_Error =
new Dictionary<string[], string[]>();
447 if (!
string.IsNullOrWhiteSpace(processMsgError))
449 allDes_Error = extraerDescripcionesdeErrores(processMsgError, out codigoError);
453 string[] clave = {
"",
"" };
454 string[] value = {
"",
"" };
455 allDes_Error.Add(clave, value);
459 foreach (KeyValuePair<
string[],
string[]> des_Error
in allDes_Error)
462 if (
string.IsNullOrWhiteSpace(des_Error.Key[1]))
471 List<RespuestaFacturaBase> itemsRespuestas = crearRespuestas(codigoError, des_Error, estado, rutaFichero);
474 respuestas.Add(item);
481 if (tag_Envio_Ticketbai.ToUpper() ==
"NO")
484 respuesta.
_Envio = tipoEnvioModelos;
486 respuesta.
_Error.
_Descripcion =
"ERROR GENERAL PROVOCADO. REVISA TU CONFIG.INI EL TAG [ENVIO_TICKETBAI]";
487 respuestas.Add(respuesta);
494 respuesta.
_Envio = tipoEnvioModelos;
497 respuestas.Add(respuesta);
510 private Dictionary<string[], string[]> extraerDescripcionesdeErrores(
string msgError, out
string codigoError)
512 string[] separador = {
"||" };
513 string[] errores = msgError.Split(separador, StringSplitOptions.None);
514 Dictionary<string[], string[]> allDes_Error =
new Dictionary<string[], string[]>();
517 codigoError = (errores.Count() > 0 ? errores[0].Split(
'|')[0] :
"");
519 foreach (
string error
in errores)
523 if (errores.Count() == 1 || count > 1)
525 string[] errorSplit =
error.Split(
'|');
526 if (errorSplit != null && errorSplit.Count() > 0)
529 ParseError(ref errorSplit);
531 string factura = (errores.Count() > 1 ? obtenerFactura(error) :
"");
532 string nif = (errores.Count() > 1 ? obtenerNif(error) :
"");
533 string[] clave = { nif, factura };
535 string[] datosError = { (
string.IsNullOrWhiteSpace(errorSplit[errorSplit.Count() - 1]) ? error : errorSplit[errorSplit.Count() - 1]), (
string.IsNullOrWhiteSpace(errorSplit[errorSplit.Count() - 1]) || count == 1 ?
"" : errorSplit[0].Trim())};
537 if (allDes_Error.ContainsKey(clave))
539 allDes_Error[clave][0] = allDes_Error[clave][0] + (
String.IsNullOrWhiteSpace(allDes_Error[clave][0]) ?
"" :
"#") + datosError;
543 allDes_Error.Add(clave, datosError);
556 private string obtenerFactura(
string error)
559 string[] errorSplit =
error.Split(
'|');
560 if (errorSplit != null && errorSplit.Count() > 3)
562 factura = (errorSplit[2].Trim().ToUpper() !=
"EMPTY" ? errorSplit[2].Trim() :
"") + (errorSplit[3].Trim().ToUpper() !=
"EMPTY" ? errorSplit[3].Trim().PadLeft(8) :
"");
571 private string obtenerNif(
string error)
574 string[] errorSplit =
error.Split(
'|');
575 if (errorSplit != null && errorSplit.Count() > 3)
578 nif = (errorSplit[1].Trim().ToUpper() !=
"EMPTY" ? (errorSplit[1].Trim().ToUpper().StartsWith(
"ES") ? errorSplit[1].Trim().Substring(2) : errorSplit[1].Trim() ) :
"").Trim();
588 private List<RespuestaFacturaBase> crearRespuestas(
string codigoError, KeyValuePair<
string[],
string[]> des_Error,
EstadoAEATModelos estado,
string tcFicheroXML)
590 IEnumerable<ILibroFila> filas = null;
591 string descripError = des_Error.Value[0];
593 if (!
string.IsNullOrWhiteSpace(des_Error.Key[1]))
595 if (_lEsLibroBienes140)
597 filas = ObtenerFilasLibroBienesCrearRespuesta(des_Error.Key[1]);
600 else if (
string.IsNullOrWhiteSpace(des_Error.Key[0]) || des_Error.Key[0] == ((
Empresa)EW_GLOBAL._Empresa)._CifTC)
603 filas = _Libro.
_Filas.Where(f => f._Seleccion && (((
DatosIVAFactucert)f)._EnvioSerieFactura.Trim() + ((
DatosIVAFactucert)f)._EnvioNumFactura.Trim().PadLeft(8)).TrimEnd() == des_Error.Key[1].TrimEnd());
611 descripError =
"Factura no encontrada." + descripError;
615 ObtenerRutaNombreFicheroRespuesta(tcFicheroXML, out
string lcRutaFicheroRespuesta, out
string lcNombreFicheroRespuesta);
617 List<RespuestaFacturaBase> localRespuestas =
new List<RespuestaFacturaBase>();
618 if (filas == null || filas.Count() == 0)
621 respuesta.
_Envio = tipoEnvioModelos;
623 respuesta.
_Factura = des_Error.Key[1].Trim();
628 respuesta.
_Libro = _Libro;
631 respuesta.
_Fichero = lcNombreFicheroRespuesta;
632 respuesta.
_NIF = des_Error.Key[0].Trim();
634 respuesta.
_MasInformacion = ObtenerMasInformacionSubcapitulo(subcapituloBien);
636 localRespuestas.Add(respuesta);
644 respuesta.
_Envio = tipoEnvioModelos;
651 respuesta.
_Libro = _Libro;
657 respuesta.
_Fichero = lcNombreFicheroRespuesta;
659 localRespuestas.Add(respuesta);
662 return localRespuestas;
671 private void ObtenerRutaNombreFicheroRespuesta(
string tcFicheroXML, out
string tcRutaFicheroRespuesta, out
string tcNombreFicheroRespuesta)
673 tcRutaFicheroRespuesta = Path.Combine(_RutaFicheroXML, (
string.IsNullOrWhiteSpace(_Libro.
_Libro) ?
"Libro" : _Libro.
_Libro.Trim()),
"respuesta");
674 tcNombreFicheroRespuesta = Path.GetFileNameWithoutExtension(tcFicheroXML) +
"_Resp" + Path.GetExtension(tcFicheroXML);
682 private IEnumerable<ILibroFila> ObtenerFilasLibroBienesCrearRespuesta(
string tcIdBien)
684 IEnumerable<ILibroFila> filasBase = null, filasExtra = null;
689 if (filasBase != null && filasBase.Count() > 0)
690 filasBase.Concat(filasExtra);
692 filasBase = filasExtra;
701 private void ProcesarResultados(
bool isSend)
703 List<ILibroFila> lolstSel = null;
705 if (!_lEsLibroBienes140)
708 lolstSel = ObtenerFilasLibroBienesProcesarResultados();
711 RespuestaFacturaBase loRespuestaFacturaBase = respuestas.Where(r =>
string.IsNullOrWhiteSpace(r._Factura)).FirstOrDefault();
713 if (loRespuestaFacturaBase == null)
716 string[] clave = {
"",
"" };
717 string[] value = {
"",
"" };
718 KeyValuePair<string[], string[]> facturaVacia =
new KeyValuePair<string[], string[]>(clave, value);
720 loRespuestaFacturaBase = crearRespuestas(mensaje, facturaVacia, estado,
"")[0];
724 if (loRespuestaFacturaBase != null)
729 if (ComprobarRespuesta(fila))
736 _Error = loRespuestaFacturaBase.
_Error,
738 _Envio = loRespuestaFacturaBase.
_Envio,
739 _Estado = loRespuestaFacturaBase.
_Estado,
743 _FechaPresentacion = DateTime.Now,
746 _MasInformacion = ObtenerMasInformacionSubcapitulo(((
DatosIVAFactucert)fila)._SubcapituloBien),
747 _Fichero = loRespuestaFacturaBase.
_Fichero,
751 _Resultado.Add(respuesta);
760 if (!
string.IsNullOrWhiteSpace(respuesta.
_Factura))
762 _Resultado.Add(respuesta);
766 if (_Resultado.Count > 0)
768 _Resultado = _Resultado.OrderBy(r => r._Factura).ToList();
777 private bool ComprobarRespuesta(
ILibroFila toFila)
781 if (!_lEsLibroBienes140)
782 llOk = respuestas.Where(r => r._Factura.Trim() == toFila.
_Factura.Trim() && r._NIF.Trim() == toFila.
_NIF.Trim() && r._IdentificacionFactura.Trim() == toFila.
_IdentificacionFactura.Trim()).Count() == 0;
794 private string ObtenerMasInformacionSubcapitulo(
SubcapituloBien teSubcapitulo)
796 if (!_lEsLibroBienes140)
799 string lcSubcapitulo =
"";
800 switch (teSubcapitulo)
803 lcSubcapitulo =
"Subcapítulo Alta de bienes";
806 lcSubcapitulo =
"Subcapítulo Regularización de bienes";
809 lcSubcapitulo =
"Subcapítulo Baja de bienes";
813 return lcSubcapitulo;
821 private List<ILibroFila> ObtenerFilasLibroBienesProcesarResultados()
826 if (lolstSel != null && lolstSel.Count > 0)
827 lolstSel.AddRange(lolstSelExtra);
829 lolstSel = lolstSelExtra;
839 string grupoactual = FUNCTIONS._Grupo_Actual();
840 string empresa = Convert.ToString(EW_GLOBAL._GetVariable(
"wc_empresa")).Trim();
842 return FACTUCERT._FactuCertConfig._ConfigFactuCertModelo._RutaExportacion.Trim() +
"\\" + grupoactual +
"\\" + empresa +
"\\" + _ModeloFiscal.
_Modelo.Trim() +
"\\files";
850 string grupoactual = FUNCTIONS._Grupo_Actual();
851 string empresa = Convert.ToString(EW_GLOBAL._GetVariable(
"wc_empresa")).Trim();
853 return FACTUCERT._FactuCertConfig._ConfigFactuCertModelo._RutaExportacion.Trim() +
"\\" + grupoactual +
"\\" + empresa +
"\\" + _ModeloFiscal.
_Modelo.Trim() +
"\\resp";
override string rutaAddonsXml()
Ruta del addons Xml
TipoOperacionLibro
Tipo de operación de envío del libro que se utiliza para generar los XML correspondientes ...
Classe empresa basada en sage.ew.ewmante
eEntornosModelos
Enumeración para el Working Mode de conectarse al Compliance necesario para poder establecer el EndPo...
TipoEnvioModelos _Envio
Tipo de envío : Pendiente, Alta, Modificación o Baja
static AddonsController Instance
Instancia al objeto singleton Addons
Clase LibroEmitidas No Certificadas
DateTime _FechaInicio
Fecha inicio
TipoEnvioModelos _ProximoEnvio
Próximo envío
string _Codigo
Coddigo error
Este es el espacio de nombres de su módulo. Puede encontrar más información y ayuda en el fichero rea...
Argumentos para los eventos lanzados por el addons en caso de error
Clase ModeloFiscalLibrosBase - Definición del modelo
TipoEnvioModelos tipoEnvioModelos
SubcapituloBien subcapituloBien
eEntornosModelos _Entorno
Devuelve un enumerado en función de los parámetros y el nombre de la página en CONFIG ...
string _Codigo
Código(Cliente, Cuenta, Proveedor)
Clase Libro Bienes de Inversión del modelo 140
DateTime _FechaPresentacion
Fecha presentación
string _IdentificacionFactura
GUID_ID registro IVA
Es como el tipo de entrada asientos pero por negocio, sin formulario, pq quiero que me haga las propu...
SubcapituloBien
Subcapítulos para el libro de bienes del 140
object GetAddon(int numaddon)
Obtiene el addon por numero
string _IdentificacionBien
Identificacion Bien
string _Cuenta
Cuenta de la factura(cliente/proveedor)
string _Fichero
Fichero de respuesta (sólo SII de momento)
string _IdentificacionFactura
Id
override void _DescargarDatos()
Descarga los resultados Vaciamos las respuestas una vez acabada la generación de todos los libros ...
Clase base de IGenerarXML
DateTime _FechaExpedicion
Fecha expedición
IModeloFiscalLibros _ModeloFiscalLibros
Referencia a ModeloFiscalLibros
override bool _GenerarXML(ILibro libro, bool isSend, Dictionary< string, object > parametros)
Metodo para generar el XML
GenerarXMLFactucert(IModeloFiscalLibros modelo)
IRespuestaError _Error
Respuesta del error
EstadoAEATModelos _Estado
Estado : Pendiente, Generado o Enviado
EstadoAEATModelos
Estado modelos
Clase de respuesta de la generación del XML
TipoEnvioModelos _ProximoEnvio
Próximo envío
IAddonsManager AddonsManager
Gestor de Addons
override string rutaAddonsLog()
Ruta del addons Log
BindingList< ILibroFila > _Filas
Contenido de las filas del listado
string _MasInformacion
Propiedad para poder indicar parámetros adicionales en la respuesta
string _Factura
Múmero de Factura
string _Libro
Nombre del libro
string _Descripcion
Descripción error
DateTime _FechaExpedicion
Fecha de expedición
TipoEnvioModelos
Tipo de envío : Pendiente, Alta, Modificación, Baja o Nada