GenerarXMLFactucert.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
6 using System.Windows.Forms;
8 using Sage.ES.S50.Modelos.Clases;
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;
14 using sage.ew.functions;
15 using sage.ew.global;
16 using System.IO;
17 using sage.ew.db;
19 using Sage.ES.S50.Modelos;
20 using sage.ew.empresa;
21 using sage.ew.contabilidad;
22 using Sage.ES.S50.Modelos._140;
24 
25 namespace sage.addons.factucert.Negocio.ModelosFiscalLibros
26 {
28  {
29  private Process _process = null;
30  private IModeloFiscalLibros _ModeloFiscal;
31  private ModeloEnum model;
32  private bool generadoXML = true;
33  private bool enviadoXML = true;
34  private ILibro _Libro;
35  private List<RespuestaFacturaBase> respuestas = new List<RespuestaFacturaBase>();
36  private string processMsgError = "";
37  private bool _lEsLibroBienes140 = false;
38 
39  protected string tag_Envio_Ticketbai = FUNCTIONS.LeerConfigIni("[ENVIO_TICKETBAI]");
42 
44  {
45  _ModeloFiscal = modelo;
46  }
47  // CreateProcess(object libro, bool isSend, ModeloEnum model)
48 
49  public override bool _GenerarXML(ILibro libro, bool isSend, Dictionary<string, object> parametros)
50  {
51  _Libro = (ILibro)libro;
52  _lEsLibroBienes140 = _Libro._Libro == "BIENESINVERSION" && _Libro._ModeloFiscalLibros._Modelo == "140";
53 
54  switch (_ModeloFiscal._Modelo)
55  {
56  case "140":
57  model = ModeloEnum.Modelo_140;
58  break;
59  case "240":
60  model = ModeloEnum.Modelo_240;
61  break;
62  }
63 
64  if (parametros.Count < 1)
65  {
66  return false;
67  }
68 
69  if (this._process == null)
70  {
71  this._process = new Process();
72  }
73 
74  Entorno(_Libro);
75 
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());
80  try
81  {
82  if (!Directory.Exists(config.TraceFile))
83  {
84  Directory.CreateDirectory(config.TraceFile);
85  }
86 
87  }
88  catch (Exception e)
89  {
90  DB.Registrar_Error(e);
91  config.TraceFile = "";
92  }
93 
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";
99 
100  config.Certificate = FACTUCERT._FactuCertConfig._ConfigFactuCertModelo._CNom;// "CERTIFICADO FISICA PRUEBAS - 99999910G";
101  config.CertificateThumbprint = "";
102 
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;
106 
107  foreach (KeyValuePair<string, object> item in parametros)
108  {
109  if (item.Key.Contains("Libro") && item.Value != null)
110  {
111  string cDate = DateTime.Now.ToString("yyyyMMdd_hhmmss");
112  if (item.Value is List<object>)
113  {
114  List<object> lItemValue = (List<object>)item.Value;
115  respuestas.Clear();
116  for (int nInd = 0; nInd < lItemValue.Count; nInd++)
117  {
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);
124  }
125 
126  }
127  else
128  {
129  tipoEnvioModelos = convertirTipoOperacionLibroEnTipoEnvioModelos((TipoOperacionLibro)(((dynamic)item.Value).Cabecera.Operacion));
130  if (_lEsLibroBienes140)
131  subcapituloBien = convertirSubcapituloEnSubcapituloBien(Convert.ToString((((dynamic)item.Value).Cabecera.Subcapitulo)));
132  respuestas.Clear();
133  GenerarEnviarXML(isSend, config, item.Value, tipoEnvioModelos.ToString(), cDate);
134  }
135 
136  try
137  {
138  if (this._process != null && isSend && _Resultado.Count == 0 && respuestas.Count == 0)
139  {
140  // Ya no llamamos a proceso enviar ya que lo hacemos a la misma vez que generamos
141  // ProcesoEnviar(config, libro, rutaFichero, tipoEnvioModelos.ToString(), cIdentificador);
142  }
143 
144  ProcesarResultados(isSend);
145  }
146  catch (Exception loEx)
147  {
148  string lcMensaje = loEx.Message;
149  // MessageBox.Show(loEx.MensajeCompleto(), "error enviar general");
150  }
151  }
152  }
153 
154  return generadoXML;
155  }
156 
161  private void Entorno(ILibro toLibro)
162  {
163  if (toLibro._Entorno == eEntornosModelos.EnvioPre)
164  _cHost = "https://pruesarrerak.bizkaia.eus/N3B4000M/aurkezpena";
165  else
166  _cHost = "https://sarrerak.bizkaia.eus/N3B4000M/aurkezpena";
167  }
168 
172  TipoEnvioModelos convertirTipoOperacionLibroEnTipoEnvioModelos(TipoOperacionLibro tipoOperacionLibro)
173  {
174  TipoEnvioModelos tipoEnvioModelos = new TipoEnvioModelos();
175 
176  switch (tipoOperacionLibro)
177  {
178  case TipoOperacionLibro.Alta:
179  tipoEnvioModelos = TipoEnvioModelos.Alta;
180  break;
181  case TipoOperacionLibro.Alta_dev_regimen_viajeros:
182  tipoEnvioModelos = TipoEnvioModelos.Alta;
183  break;
184  case TipoOperacionLibro.Modificacion:
185  tipoEnvioModelos = TipoEnvioModelos.Modificacion;
186  break;
187  case TipoOperacionLibro.Modificacion_dev_regimen_viajeros:
188  tipoEnvioModelos = TipoEnvioModelos.Modificacion;
189  break;
190  case TipoOperacionLibro.Anulacion:
191  tipoEnvioModelos = TipoEnvioModelos.Baja;
192  break;
193  }
194 
195  return tipoEnvioModelos;
196  }
197 
203  SubcapituloBien convertirSubcapituloEnSubcapituloBien(string tcSubcapituloBien140)
204  {
205  SubcapituloBien leSub = SubcapituloBien.Alta;
206  string lcSub140 = tcSubcapituloBien140.ToLower().Trim();
207 
208  switch (lcSub140)
209  {
210  case "alta_bienes_afectos_o_inversion":
211  leSub = SubcapituloBien.Alta;
212  break;
213 
214  case "regularizacion_anual_bienes_inversion":
215  leSub = SubcapituloBien.Regularizacion;
216  break;
217 
218  case "baja_bienes_afectos_o_inversión":
219  leSub = SubcapituloBien.Baja;
220  break;
221  }
222 
223  return leSub;
224  }
225 
230  public override void _DescargarDatos()
231  {
232  _Resultado.Clear();
233  respuestas.Clear();
234  }
235 
236  private string _cHost = $"https://pruesarrerak.bizkaia.eus/N3B4000M/aurkezpen";
237 
238  private void GenerarEnviarXML(bool isSend, IConfig config, object libro, string key, string cIdentificador)
239  {
240  string rutaFichero = _RutaFicheroXML + "\\" + (string.IsNullOrWhiteSpace(_Libro._Libro) ? "Libro" : _Libro._Libro.Trim());
241  try
242  {
243  if (!Directory.Exists(rutaFichero))
244  {
245  Directory.CreateDirectory(rutaFichero);
246  }
247 
248  }
249  catch (Exception e)
250  {
251  DB.Registrar_Error(e);
252  rutaFichero = "";
253  }
254  rutaFichero = rutaFichero + "\\" + cIdentificador + "_" + key.ToLower().Replace("libro", "").Trim() + ".xml";
255 
256  if (this._process != null)
257  {
258  ProcesoGenerar(config, libro, rutaFichero, isSend, key, cIdentificador);
259  }
260 
261  }
262 
279  private void ParseError(ref string[] taErrorSplit)
280  {
281  if (taErrorSplit.Length < 2) // Validamos la longitud
282  return;
283 
284  int lnIndice = taErrorSplit.Length - 1;
285 
286  string lcError = taErrorSplit[lnIndice].ToUpper().Trim();
287 
288  if (lcError == "EMPTY")
289  {
290  string lcCodigo = taErrorSplit[lnIndice - 1].Trim();
291 
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} ." : "");
294  }
295  else
296  {
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")))
300  {
301  taErrorSplit[lnIndice] = ((ModeloFiscalLibrosBase)_ModeloFiscal)._MensajeTiempoEsperaExcedidoServicio;
302  }
303  }
304  }
305 
306  private void ProcesoGenerar(IConfig config, object libro, string rutaFichero, bool isSend, string key, string cIdentificador)
307  {
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; // Si es false al generar envía tambien.
314  config.SendFact.Host = config.SendFact.Host = _cHost;
315 
316  generadoXML = this._process.GenerateCom();
317  processMsgError = "";
318 
319  try
320  {
321  processMsgError = (_process != null && !string.IsNullOrWhiteSpace(_process.MsgError) ? _process.MsgError : "");
322 
323  }
324  catch
325  {
326  // Pongo try-catch por cuando el proceso es correcto y no devuelve nada en _process.MsgError da un error al hacer el !string.IsNullOrWhiteSpace(_process.MsgError) y así lo solvento
327  processMsgError = "";
328  }
329 
330 
331  string listaFacturas = "";
332  List<ILibroFila> lolstSel = _Libro._Filas.Where(f => f._Seleccion && (f._ProximoEnvio == tipoEnvioModelos || f._ProximoEnvio == TipoEnvioModelos.Nada)).ToList(); // Filtramos las seleccionadas
333  foreach (ILibroFila fila in lolstSel)
334  {
335  listaFacturas += fila._Factura + ";";
336  }
337 
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);
339  factucert factucert = (factucert)Sage.ES.S50.Addons.AddonsController.Instance.AddonsManager.GetAddon("FACTUCERT");
340  factucert.Log(ew.enumerations.TipoMensaje.Info, lcLog, "_Envio Modelo_" + _ModeloFiscal._Modelo + "_" + key + "_" + cIdentificador);
341 
342  enviadoXML = generadoXML & isSend;
343 
344  string codigoError = "";
345  Dictionary<string[], string[]> allDes_Error = new Dictionary<string[], string[]>();
346 
347  if (!string.IsNullOrWhiteSpace(processMsgError))
348  {
349  allDes_Error = extraerDescripcionesdeErrores(processMsgError, out codigoError);
350  }
351  else
352  {
353  string[] clave = { "", "" };
354  string[] value = { "", "" };
355  allDes_Error.Add(clave, value);
356  }
357 
358  // Me recorro los errores extraidos y creo las repuestas
359  foreach (KeyValuePair<string[], string[]> des_Error in allDes_Error)
360  {
361  EstadoAEATModelos estado;
362  if (string.IsNullOrWhiteSpace(des_Error.Key[1])) // si es un error para todas las facturas
363  {
364  estado = (enviadoXML ? (string.IsNullOrWhiteSpace(processMsgError) ? EstadoAEATModelos.Aceptada : EstadoAEATModelos.AceptadaConErrores) : EstadoAEATModelos.Rechazada);
365  }
366  else // Error para una factura en concreto de numero des_Error.Key
367  {
368  estado = (des_Error.Value[1].Trim().ToUpper() == "CORRECTO" ? EstadoAEATModelos.Aceptada : (des_Error.Value[1].Trim().ToUpper() == "INCORRECTO" ? EstadoAEATModelos.Rechazada : EstadoAEATModelos.AceptadaConErrores)); // ACEPTADOCONERRORES
369  }
370 
371  List<RespuestaFacturaBase> itemsRespuestas = crearRespuestas(codigoError, des_Error, estado, rutaFichero);
372  foreach (RespuestaFacturaBase item in itemsRespuestas)
373  {
374  respuestas.Add(item);
375  }
376  }
377 
378  // MessageBox.Show((generadoXML ? "GENERADO:" : "NO GENERADO:") + processMsgError, "Respuesta");
379 
380  }
381 
385  private void ProcesoEnviar(IConfig config, object libro, string rutaFichero, string key, string cIdentificador)
386  {
387 
388  if (String.IsNullOrWhiteSpace(tag_Envio_Ticketbai))
389  {
390  this._process.Model = model;
391 
392  try
393  {
394  this._process.TypeBook = libro;
395  }
396  catch (Exception loEx)
397  {
398  string lcMensaje = loEx.Message;
399  // MessageBox.Show(lcMensaje,"error enviar1");
400  }
401 
402  config.SendFact = new SendFact();
403  config.SendFact.XmlFact = rutaFichero;
404  config.EnvioDiferido = true;
405  config.SendFact.Host = _cHost;
406 
407  enviadoXML = false;
408 
409  try
410  {
411  enviadoXML = this._process.Send();
412  }
413  catch (Exception loEx)
414  {
415  string lcMensaje = loEx.Message;
416  // MessageBox.Show(lcMensaje, "error enviar 2");
417  }
418 
419  string codigoError = "";
420  processMsgError = "";
421  try
422  {
423  processMsgError = (_process != null && !string.IsNullOrWhiteSpace(_process.MsgError) ? _process.MsgError : "");
424 
425  }
426  catch
427  {
428  // Pongo try-catch por cuando el proceso es correcto y no devuelve nada en _process.MsgError da un error al hacer el !string.IsNullOrWhiteSpace(_process.MsgError) y así lo solvento
429  processMsgError = "";
430 
431  string listaFacturas = "";
432  List<ILibroFila> lolstSel = _Libro._Filas.Where(f => f._Seleccion && (f._ProximoEnvio == tipoEnvioModelos || f._ProximoEnvio == TipoEnvioModelos.Nada)).ToList(); // Filtramos las seleccionadas
433  foreach (ILibroFila fila in lolstSel)
434  {
435  listaFacturas += fila._Factura + ";";
436  }
437 
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);
439  factucert factucert = (factucert)Sage.ES.S50.Addons.AddonsController.Instance.AddonsManager.GetAddon("FACTUCERT");
440  factucert.Log(ew.enumerations.TipoMensaje.Info, lcLog, "_Envio Modelo_" + _ModeloFiscal._Modelo + "_" + key + "_" + cIdentificador);
441 
442  }
443  // MessageBox.Show((enviadoXML ? "ENVIADO:" : "NO ENVIADO:") + processMsgError, "Respuesta");
444 
445  Dictionary<string[], string[]> allDes_Error = new Dictionary<string[], string[]>();
446 
447  if (!string.IsNullOrWhiteSpace(processMsgError))
448  {
449  allDes_Error = extraerDescripcionesdeErrores(processMsgError, out codigoError);
450  }
451  else
452  {
453  string[] clave = { "", "" };
454  string[] value = { "", "" };
455  allDes_Error.Add(clave, value);
456  }
457 
458  // Me recorro los errores extraidos y creo las repuestas
459  foreach (KeyValuePair<string[], string[]> des_Error in allDes_Error)
460  {
461  EstadoAEATModelos estado;
462  if (string.IsNullOrWhiteSpace(des_Error.Key[1])) // si es un error para todas las facturas
463  {
464  estado = (enviadoXML ? (string.IsNullOrWhiteSpace(processMsgError) ? EstadoAEATModelos.Aceptada : EstadoAEATModelos.AceptadaConErrores) : EstadoAEATModelos.Rechazada);
465  }
466  else // Error para una factura en concreto de numero des_Error.Key
467  {
468  estado = (des_Error.Value[1].Trim().ToUpper() == "CORRECTO" ? EstadoAEATModelos.Aceptada : (des_Error.Value[1].Trim().ToUpper() == "INCORRECTO" ? EstadoAEATModelos.Rechazada : EstadoAEATModelos.AceptadaConErrores)); // ACEPTADOCONERRORES
469  }
470 
471  List<RespuestaFacturaBase> itemsRespuestas = crearRespuestas(codigoError, des_Error, estado, rutaFichero);
472  foreach (RespuestaFacturaBase item in itemsRespuestas)
473  {
474  respuestas.Add(item);
475  }
476  }
477 
478  }
479  else
480  {
481  if (tag_Envio_Ticketbai.ToUpper() == "NO")
482  {
483  RespuestaFacturaBase respuesta = new RespuestaFacturaBase();
484  respuesta._Envio = tipoEnvioModelos;
485  respuesta._Estado = EstadoAEATModelos.Rechazada;
486  respuesta._Error._Descripcion = "ERROR GENERAL PROVOCADO. REVISA TU CONFIG.INI EL TAG [ENVIO_TICKETBAI]";
487  respuestas.Add(respuesta);
488 
489  enviadoXML = false;
490  }
491  else
492  {
493  RespuestaFacturaBase respuesta = new RespuestaFacturaBase();
494  respuesta._Envio = tipoEnvioModelos;
495  respuesta._Estado = EstadoAEATModelos.Aceptada;
496  respuesta._Error._Descripcion = "";// "ACEPTADA GENERAL PROVOCADO. REVISA TU CONFIG.INI EL TAG [ENVIO_TICKETBAI]";
497  respuestas.Add(respuesta);
498 
499  enviadoXML = true;
500  }
501  }
502  }
503 
510  private Dictionary<string[], string[]> extraerDescripcionesdeErrores(string msgError, out string codigoError)
511  {
512  string[] separador = { "||" };
513  string[] errores = msgError.Split(separador, StringSplitOptions.None);
514  Dictionary<string[], string[]> allDes_Error = new Dictionary<string[], string[]>();
515  int count = 0;
516 
517  codigoError = (errores.Count() > 0 ? errores[0].Split('|')[0] : "");
518 
519  foreach (string error in errores)
520  {
521  count++;
522 
523  if (errores.Count() == 1 || count > 1) // Si solo hay un error es el genérico y lo añadimos, pero si hay mas de uno obviamos el generico que es el primero y solo cogemos los errores por factura.
524  {
525  string[] errorSplit = error.Split('|');
526  if (errorSplit != null && errorSplit.Count() > 0)
527  {
528 
529  ParseError(ref errorSplit);
530 
531  string factura = (errores.Count() > 1 ? obtenerFactura(error) : "");
532  string nif = (errores.Count() > 1 ? obtenerNif(error) : "");
533  string[] clave = { nif, factura };
534  // Si la descripción del error viene vacia guardo el error completo
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())};
536 
537  if (allDes_Error.ContainsKey(clave)) // siya ha habido un error para esta factura le sumo la nueva desripcion a la antigua para que pueda visualizar las dos
538  {
539  allDes_Error[clave][0] = allDes_Error[clave][0] + (String.IsNullOrWhiteSpace(allDes_Error[clave][0]) ? "" : "#") + datosError;
540  }
541  else
542  {
543  allDes_Error.Add(clave, datosError);
544  }
545 
546  }
547  }
548 
549  }
550  return allDes_Error;
551  }
552 
556  private string obtenerFactura(string error)
557  {
558  string factura = "";
559  string[] errorSplit = error.Split('|');
560  if (errorSplit != null && errorSplit.Count() > 3)
561  {
562  factura = (errorSplit[2].Trim().ToUpper() != "EMPTY" ? errorSplit[2].Trim() : "") + (errorSplit[3].Trim().ToUpper() != "EMPTY" ? errorSplit[3].Trim().PadLeft(8) : "");//TODO Verificar cuantos espacios hay que poner entre serie y numero
563  }
564 
565  return factura;
566  }
567 
571  private string obtenerNif(string error)
572  {
573  string nif = "";
574  string[] errorSplit = error.Split('|');
575  if (errorSplit != null && errorSplit.Count() > 3)
576  {
577  // Quitamos el "ES" del nif porque puede venir de IDOtro relleno con este y si no lo quitamos no encontrariamos la factura...
578  nif = (errorSplit[1].Trim().ToUpper() != "EMPTY" ? (errorSplit[1].Trim().ToUpper().StartsWith("ES") ? errorSplit[1].Trim().Substring(2) : errorSplit[1].Trim() ) : "").Trim();
579  }
580 
581  return nif;
582  }
583 
584 
588  private List<RespuestaFacturaBase> crearRespuestas(string codigoError, KeyValuePair<string[], string[]> des_Error, EstadoAEATModelos estado, string tcFicheroXML)
589  {
590  IEnumerable<ILibroFila> filas = null;
591  string descripError = des_Error.Value[0];
592 
593  if (!string.IsNullOrWhiteSpace(des_Error.Key[1]))
594  {
595  if (_lEsLibroBienes140)
596  {
597  filas = ObtenerFilasLibroBienesCrearRespuesta(des_Error.Key[1]);
598  }
599  // En el caso de ingresos y gastos sin factura también llega NIF. Quito la condición que sea cliente
600  else if (string.IsNullOrWhiteSpace(des_Error.Key[0]) || des_Error.Key[0] == ((Empresa)EW_GLOBAL._Empresa)._CifTC) // Ventas no trae nif y solo buscamos por factura o si viene el nif de la empresa.
601  {
602  // Consideramos que son ventas por lo cual despreciamos si hay alguna de compras por si coincide que se manden facturas con el mismo numero y unas de compras y otras de ventas. Siempre cogeremos las de Ventas
603  filas = _Libro._Filas.Where(f => f._Seleccion && (((DatosIVAFactucert)f)._EnvioSerieFactura.Trim() + ((DatosIVAFactucert)f)._EnvioNumFactura.Trim().PadLeft(8)).TrimEnd() == des_Error.Key[1].TrimEnd()); // Filtramos las seleccionadas
604  }
605  else // compras : viene el nif y buscamos por él
606  {
607  filas = _Libro._Filas.Where(f => f._Seleccion && ((DatosIVAFactucert)f)._NIF.Trim() + ((DatosIVAFactucert)f)._EnvioSerieFactura.Trim() + ((DatosIVAFactucert)f)._EnvioNumFactura.Trim().PadLeft(8) == des_Error.Key[0].Trim() + des_Error.Key[1].TrimEnd()); // Filtramos las seleccionadas
608  }
609  if( filas == null)
610  {
611  descripError = "Factura no encontrada." + descripError;
612  }
613  }
614 
615  ObtenerRutaNombreFicheroRespuesta(tcFicheroXML, out string lcRutaFicheroRespuesta, out string lcNombreFicheroRespuesta);
616 
617  List<RespuestaFacturaBase> localRespuestas = new List<RespuestaFacturaBase>();
618  if (filas == null || filas.Count() == 0)
619  {
620  RespuestaFacturaBase respuesta = new RespuestaFacturaBase();
621  respuesta._Envio = tipoEnvioModelos;
622  respuesta._Estado = estado;
623  respuesta._Factura = des_Error.Key[1].Trim();
624  respuesta._IdentificacionFactura = "";
625  respuesta._Error._Codigo = codigoError;
626  respuesta._Error._Descripcion = descripError;
627  respuesta._FechaPresentacion = DateTime.Now;
628  respuesta._Libro = _Libro;
629  respuesta._Cuenta = "";
630  respuesta._RutaFichero = lcRutaFicheroRespuesta;
631  respuesta._Fichero = lcNombreFicheroRespuesta;
632  respuesta._NIF = des_Error.Key[0].Trim();
633  respuesta._FechaExpedicion = Convert.ToDateTime(null);
634  respuesta._MasInformacion = ObtenerMasInformacionSubcapitulo(subcapituloBien);
635 
636  localRespuestas.Add(respuesta);
637  }
638  else
639  {
640  foreach (ILibroFila fila in filas)
641  {
642  // Bug 190698 Rellenamos con la misma respuesta de error todos los registros de la factura ya que no sabemos cual de ellos es el cre ha producido el error.
643  RespuestaFacturaBase respuesta = new RespuestaFacturaBase();
644  respuesta._Envio = tipoEnvioModelos;
645  respuesta._Estado = estado;
646  respuesta._Factura = (_lEsLibroBienes140 ? fila._IdentificacionBien : fila._Factura);
648  respuesta._Error._Codigo = codigoError;
649  respuesta._Error._Descripcion = descripError;
650  respuesta._FechaPresentacion = DateTime.Now;
651  respuesta._Libro = _Libro;
652  respuesta._Cuenta = fila._Codigo;
653  respuesta._NIF = fila._NIF;
654  respuesta._FechaExpedicion = Convert.ToDateTime((_lEsLibroBienes140 ? fila._FechaInicio : fila._FechaExpedicion));
655  respuesta._MasInformacion = ObtenerMasInformacionSubcapitulo(((DatosIVAFactucert)fila)._SubcapituloBien);
656  respuesta._RutaFichero = lcRutaFicheroRespuesta;
657  respuesta._Fichero = lcNombreFicheroRespuesta;
658 
659  localRespuestas.Add(respuesta);
660  }
661  }
662  return localRespuestas;
663  }
664 
671  private void ObtenerRutaNombreFicheroRespuesta(string tcFicheroXML, out string tcRutaFicheroRespuesta, out string tcNombreFicheroRespuesta)
672  {
673  tcRutaFicheroRespuesta = Path.Combine(_RutaFicheroXML, (string.IsNullOrWhiteSpace(_Libro._Libro) ? "Libro" : _Libro._Libro.Trim()), "respuesta");
674  tcNombreFicheroRespuesta = Path.GetFileNameWithoutExtension(tcFicheroXML) + "_Resp" + Path.GetExtension(tcFicheroXML);
675  }
676 
682  private IEnumerable<ILibroFila> ObtenerFilasLibroBienesCrearRespuesta(string tcIdBien)
683  {
684  IEnumerable<ILibroFila> filasBase = null, filasExtra = null;
685 
686  filasBase = _Libro._Filas.Where(f => f._Seleccion && f._ProximoEnvio == tipoEnvioModelos && ((DatosIVAFactucert)f)._SubcapituloBien == subcapituloBien && (((DatosIVAFactucert)f)._IdentificacionBien.Trim() == tcIdBien.TrimEnd()));
687  filasExtra = ((Sage.ES.S50.Modelos._140.LibroBienesInversion)_Libro)._FilasExtra.Where(f => f._Seleccion && f._ProximoEnvio == tipoEnvioModelos && ((DatosIVAFactucert)f)._SubcapituloBien == subcapituloBien && (((DatosIVAFactucert)f)._IdentificacionBien.Trim() == tcIdBien.TrimEnd()));
688 
689  if (filasBase != null && filasBase.Count() > 0)
690  filasBase.Concat(filasExtra);
691  else
692  filasBase = filasExtra;
693 
694  return filasBase;
695  }
696 
697 
701  private void ProcesarResultados(bool isSend)
702  {
703  List<ILibroFila> lolstSel = null;
704 
705  if (!_lEsLibroBienes140)
706  lolstSel = _Libro._Filas.Where(f => f._Seleccion && (f._ProximoEnvio == tipoEnvioModelos || f._ProximoEnvio == TipoEnvioModelos.Nada)).ToList(); // Filtramos las seleccionadas
707  else
708  lolstSel = ObtenerFilasLibroBienesProcesarResultados();
709 
710  // Asignamos el primer error que no tenga numero de factura para posteriormente crear errores en todas las facturas que no hayan dado error.
711  RespuestaFacturaBase loRespuestaFacturaBase = respuestas.Where(r => string.IsNullOrWhiteSpace(r._Factura)).FirstOrDefault();
712 
713  if (loRespuestaFacturaBase == null) // Si no tenemos ningún error generico para todas las facturas creamos uno para que las facturas que no devuelvan error para que queden como aceptadas
714  {
715  EstadoAEATModelos estado = EstadoAEATModelos.Aceptada ;
716  string[] clave = { "", "" };
717  string[] value = { "", "" };
718  KeyValuePair<string[], string[]> facturaVacia = new KeyValuePair<string[], string[]>(clave, value);
719  string mensaje = "";
720  loRespuestaFacturaBase = crearRespuestas(mensaje, facturaVacia, estado,"")[0];// crearRespuesta(mensaje, facturaVacia, estado);
721  }
722 
723  int numResp = 0;
724  if (loRespuestaFacturaBase != null)
725  {
726  foreach (ILibroFila fila in lolstSel)
727  {
728  // si no encontramos una respuesta especifica para esa factura añadimos una respuesta para esa factura generica que la sacamos de loRespuestaFacturaBase
729  if (ComprobarRespuesta(fila))
730  {
731  if (fila._ProximoEnvio == loRespuestaFacturaBase._Envio || fila._ProximoEnvio == TipoEnvioModelos.Nada && loRespuestaFacturaBase._Envio == TipoEnvioModelos.Modificacion)
732  {
733  numResp++;
735  {
736  _Error = loRespuestaFacturaBase._Error,
737  _Cuenta = fila._Codigo,
738  _Envio = loRespuestaFacturaBase._Envio, // fila._ProximoEnvio,
739  _Estado = loRespuestaFacturaBase._Estado,
740  _Factura = (_lEsLibroBienes140 ? fila._IdentificacionBien : fila._Factura),
741  _IdentificacionFactura = fila._IdentificacionFactura,
742  _FechaExpedicion = Convert.ToDateTime((_lEsLibroBienes140 ? fila._FechaInicio : fila._FechaExpedicion)),
743  _FechaPresentacion = DateTime.Now,
744  _Libro = _Libro,
745  _NIF = fila._NIF,
746  _MasInformacion = ObtenerMasInformacionSubcapitulo(((DatosIVAFactucert)fila)._SubcapituloBien),
747  _Fichero = loRespuestaFacturaBase._Fichero,
748  _RutaFichero=loRespuestaFacturaBase._RutaFichero
749 
750  };
751  _Resultado.Add(respuesta);
752  }
753  }
754  }
755  }
756 
757  // pasamos a _Resultado todas las respuestas que NO tengan la _Factura vacia
758  foreach (RespuestaFacturaBase respuesta in respuestas)
759  {
760  if (!string.IsNullOrWhiteSpace(respuesta._Factura))
761  {
762  _Resultado.Add(respuesta);
763  }
764  }
765 
766  if (_Resultado.Count > 0)
767  {
768  _Resultado = _Resultado.OrderBy(r => r._Factura).ToList(); // Ordenamos la lista por factura
769  }
770  }
771 
777  private bool ComprobarRespuesta(ILibroFila toFila)
778  {
779  bool llOk = false;
780 
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;
783  else
784  llOk = respuestas.Where(r => r._Factura.Trim() == toFila._IdentificacionBien.Trim() && r._NIF.Trim() == toFila._NIF.Trim() && r._IdentificacionFactura.Trim() == toFila._IdentificacionFactura.Trim()).Count() == 0;
785 
786  return llOk;
787  }
788 
794  private string ObtenerMasInformacionSubcapitulo(SubcapituloBien teSubcapitulo)
795  {
796  if (!_lEsLibroBienes140)
797  return "";
798 
799  string lcSubcapitulo = "";
800  switch (teSubcapitulo)
801  {
802  case SubcapituloBien.Alta:
803  lcSubcapitulo = "Subcapítulo Alta de bienes";
804  break;
805  case SubcapituloBien.Regularizacion:
806  lcSubcapitulo = "Subcapítulo Regularización de bienes";
807  break;
808  case SubcapituloBien.Baja:
809  lcSubcapitulo = "Subcapítulo Baja de bienes";
810  break;
811  }
812 
813  return lcSubcapitulo;
814  }
815 
821  private List<ILibroFila> ObtenerFilasLibroBienesProcesarResultados()
822  {
823  List<ILibroFila> lolstSel = _Libro._Filas.Where(f => f._Seleccion && ((DatosIVAFactucert)f)._SubcapituloBien == subcapituloBien && (f._ProximoEnvio == tipoEnvioModelos || f._ProximoEnvio == TipoEnvioModelos.Nada)).ToList();
824  List<ILibroFila> lolstSelExtra = ((Sage.ES.S50.Modelos._140.LibroBienesInversion)_Libro)._FilasExtra.Where(f => f._Seleccion && ((DatosIVAFactucert)f)._SubcapituloBien == subcapituloBien && (f._ProximoEnvio == tipoEnvioModelos || f._ProximoEnvio == TipoEnvioModelos.Nada)).ToList();
825 
826  if (lolstSel != null && lolstSel.Count > 0)
827  lolstSel.AddRange(lolstSelExtra);
828  else
829  lolstSel = lolstSelExtra;
830 
831  return lolstSel;
832  }
833 
837  protected override string rutaAddonsXml()
838  {
839  string grupoactual = FUNCTIONS._Grupo_Actual();
840  string empresa = Convert.ToString(EW_GLOBAL._GetVariable("wc_empresa")).Trim();
841 
842  return FACTUCERT._FactuCertConfig._ConfigFactuCertModelo._RutaExportacion.Trim() + "\\" + grupoactual + "\\" + empresa + "\\" + _ModeloFiscal._Modelo.Trim() + "\\files";
843  }
844 
848  protected override string rutaAddonsLog()
849  {
850  string grupoactual = FUNCTIONS._Grupo_Actual();
851  string empresa = Convert.ToString(EW_GLOBAL._GetVariable("wc_empresa")).Trim();
852 
853  return FACTUCERT._FactuCertConfig._ConfigFactuCertModelo._RutaExportacion.Trim() + "\\" + grupoactual + "\\" + empresa + "\\" + _ModeloFiscal._Modelo.Trim() + "\\resp";
854  }
855  }
856 }
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
Definition: clsEmpresa.cs:48
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
TipoEnvioModelos _ProximoEnvio
Próximo envío
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
eEntornosModelos _Entorno
Devuelve un enumerado en función de los parámetros y el nombre de la página en CONFIG ​ ...
Definition: ILibro.cs:94
string _Codigo
Código(Cliente, Cuenta, Proveedor)
Definition: ILibroFila.cs:61
Clase Libro Bienes de Inversión del modelo 140
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
Definition: Enums.cs:721
object GetAddon(int numaddon)
Obtiene el addon por numero
string _IdentificacionBien
Identificacion Bien
Definition: ILibroFila.cs:322
string _Cuenta
Cuenta de la factura(cliente/proveedor)
string _Fichero
Fichero de respuesta (sólo SII de momento)
override void _DescargarDatos()
Descarga los resultados Vaciamos las respuestas una vez acabada la generación de todos los libros ...
IModeloFiscalLibros _ModeloFiscalLibros
Referencia a ModeloFiscalLibros
Definition: ILibro.cs:104
override bool _GenerarXML(ILibro libro, bool isSend, Dictionary< string, object > parametros)
Metodo para generar el XML
EstadoAEATModelos _Estado
Estado : Pendiente, Generado o Enviado
EstadoAEATModelos
Estado modelos
TipoEnvioModelos _ProximoEnvio
Próximo envío
Definition: ILibroFila.cs:237
IAddonsManager AddonsManager
Gestor de Addons
BindingList< ILibroFila > _Filas
Contenido de las filas del listado
Definition: ILibro.cs:64
string _MasInformacion
Propiedad para poder indicar parámetros adicionales en la respuesta
string _Libro
Nombre del libro
Definition: ILibro.cs:38
DateTime _FechaExpedicion
Fecha de expedición
Definition: ILibroFila.cs:132
TipoEnvioModelos
Tipo de envío : Pendiente, Alta, Modificación, Baja o Nada