ExportadorFactuCertXML_TBai.cs
1 #define SuplidosDtosPortes
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Security;
6 using System.Text;
7 using sage.ew.contabilidad;
8 using sage.ew.docventatpv;
9 using Sage.ES.TicketBAI.Entities;
10 using ComModel = Sage.ES.TicketBAI.Entities.ComModel;
11 using Sage.ES.TicketBAI.Entities.ComModel.Common.V1_0;
12 using Sage.ES.TicketBAI.Entities.ComModel.Invoice.V1_0;
13 using Sage.ES.TicketBAI.Entities.ComModel.Annulation.V1_0;
14 using Sage.ES.TicketBAI.Interfaces.Entities;
16 using sage.ew.global;
17 using System.Data;
18 using sage.ew.functions;
19 using sage.ew.db;
21 
22 namespace sage.addons.factucert.Negocio.Clases
23 {
24  internal class CertificadorSage50_TBaiImpl : CertificadorSage50_Base
25  {
26  private Process _process = null;
27 
28 
29  public override bool CreateProcess(string outputFilename, string territorio200, bool onlineSendFile, bool isCancellation, ref object _process, DateTime documentDate)
30  {
31  if (_process == null)
32  {
33  _process = new Sage.ES.TicketBAI.Entities.Process();
34 
35  Sage.ES.TicketBAI.Interfaces.Entities.IConfig config = new Sage.ES.TicketBAI.Entities.Config()
36  {
37  DeleteFiles = !_ActiveTraces,
38 
39  TraceAdditionalInfo = "{date} | pid:{pid} | t:{tid} | {assembly}",
40  TraceConfigFile = "",
41  TraceFile = "C:\\Logs\\Sage.ES.TicketBAI\\traces.log",
42  TraceHeaderSeparator = "",
43  TraceMaxArchivedFiles = "7",
44  TraceMode = "All",
45  TracePatternDateTime = "{LOCAL}dd/MM/yyyy HH:mm:ss.fff",
46  TraceRollSizeKB = "10000"
47  };
48 
49  if (UseCertificateFile)
50  {
51  config.CertificateFileName = CertificateName;
52  if (CertificatePassword != null)
53  config.CertificatePassword = CertificatePassword.ToString();
54  }
55  else
56  {
57  config.Certificate = CertificateName;
58  if (CertificatePassword != null)
59  config.CertificateThumbprint = CertificatePassword.ToString();
60 
61  config.VersionXAd = Sage.ES.TicketBAI.Interfaces.Entities.VersionXAd.ver_EPES;
62  config.CertificateStore = Sage.ES.TicketBAI.Interfaces.Entities.CertificateStore.cert_MY;
63  config.SignatureAlgorithm = Sage.ES.TicketBAI.Interfaces.Entities.SignatureAlgorithm.alg_SHA256;
64  }
65 
66  config.SigPolicyId_Description = GetSigPolicyId_Description(ConvertirTerritorioDe200A50(territorio200));
67  config.SigPolicyId_Identifier = GetSigPolicyId_Identifier(ConvertirTerritorioDe200A50(territorio200)); //Task 186116 => Valores diferentes por territorio
68  config.SigPolicyHash_DigestValue = GetSigPolicyHash_DigestValue(ConvertirTerritorioDe200A50(territorio200)); //Task 186116 => Nuevo parámetro a informar
69 
70  ((Sage.ES.TicketBAI.Entities.Process)_process).Config = config;
71 
72  //Nuevo componente Task 180810
73  ((Sage.ES.TicketBAI.Entities.Process)_process).Config.UrlQR = GetCertificationQRURL(ConvertirTerritorioDe200A50(territorio200));
74  }
75 
76  //Nuevo Componente
77  string URLEnvio = GetCertificationSendURL(ConvertirTerritorioDe200A50(territorio200), isCancellation, documentDate);
78  if (onlineSendFile && !string.IsNullOrWhiteSpace(URLEnvio))
79  {
80  ((Sage.ES.TicketBAI.Entities.Process)_process).Config.SendFact = new Sage.ES.TicketBAI.Entities.SendFact
81  {
82  Host = URLEnvio,
83  Territorio = territorio200,
84  XmlFact = outputFilename
85  };
86  ((Sage.ES.TicketBAI.Entities.Process)_process).Config.EnvioDiferido = true;
87  }
88  else if (!onlineSendFile)
89  {
90  ((Sage.ES.TicketBAI.Entities.Process)_process).Config.SendFact = null;
91  ((Sage.ES.TicketBAI.Entities.Process)_process).Config.EnvioDiferido = true;
92  }
93  else
94  {
95  //Se pide un envío pero no dispongo de la URL necesaria
96  return false;
97  }
98 
99  ((Sage.ES.TicketBAI.Entities.Process)_process).OutputFileName = outputFilename;
100  return true;
101  }
102 
103  public override bool GenerateDataForInvoices(string outputFilename, List<ewDocVentaTPV> listaDatosAlbaranes, AsientosFacturasVentaGenerador datosFactura, TicketBai_XML_Parameters XML_generator_parameters)
104  {
105  return GenerateTicketBaiDataInternal(outputFilename, listaDatosAlbaranes, datosFactura, XML_generator_parameters);
106  }
107 
108  public override bool GenerateDataForTickets(string outputFilename, ewDocVentaTPV datosTicket, TicketBai_XML_Parameters XML_generator_parameters)
109  {
110  return GenerateTicketBaiDataTicketsInternal(outputFilename, datosTicket, XML_generator_parameters);
111  }
112 
113  public override bool GenerateDataForAnnulment(string outputFilename, HuellaDetalle huellaFraOriginal)
114  {
115  return GenerateAnulationDataInternal(outputFilename, huellaFraOriginal);
116  }
117 
118  private static string GetSigPolicyId_Identifier(string territorio)
119  {
120  #region Validaciones previas
121 
122  //territorio 1 Araba, 2 Guipuzkoa 3 Bizkaia
123  int territorio50 = Convert.ToInt32(territorio);
124 
125  if (!territorio50.Equals(1) && !territorio50.Equals(2) && !territorio50.Equals(3))
126  throw new NotSupportedException($"Territorio no soportado {territorio50}");
127 
128  #endregion Validaciones previas
129 
130  return ExportadorFactuCertXML.Territorios.ObtenerConfiguracion(territorio50, FunctionsFactuCert._GetEntorno()).SigPolicyId_Identifier;
131  }
132 
133  private static string GetSigPolicyHash_DigestValue(string territorio)
134  {
135  #region Validaciones previas
136 
137  //territorio 1 Araba, 2 Guipuzkoa 3 Bizkaia
138  int territorio50 = Convert.ToInt32(territorio);
139 
140  if (!territorio50.Equals(1) && !territorio50.Equals(2) && !territorio50.Equals(3))
141  throw new NotSupportedException($"Territorio no soportado {territorio50}");
142 
143  #endregion Validaciones previas
144 
145  return ExportadorFactuCertXML.Territorios.ObtenerConfiguracion(territorio50, FunctionsFactuCert._GetEntorno()).SigPolicyHash_DigestValue;
146  }
147 
148  private static string GetSigPolicyId_Description(string territorio)
149  {
150  #region Validaciones previas
151 
152  //territorio 1 Araba, 2 Guipuzkoa 3 Bizkaia
153  int territorio50 = Convert.ToInt32(territorio);
154 
155  if (!territorio50.Equals(1) && !territorio50.Equals(2) && !territorio50.Equals(3))
156  throw new NotSupportedException($"Territorio no soportado {territorio50}");
157 
158  #endregion Validaciones previas
159 
160  return ExportadorFactuCertXML.Territorios.ObtenerConfiguracion(territorio50, FunctionsFactuCert._GetEntorno()).SigPolicyId_Description;
161  }
162 
163  private DetalleIVATypeCom GenerarDetalleIvaTypoCom(AsientosFacturasVentaGenerador.TipoIvaLinea iva, AsientosFacturasVentaGenerador datosFactura, EntregasEnFactura datosEntregas)
164  {
165  var baseIva = iva._Base;
166  var totalIva = iva._TotalIva;
167  var recargoIva = iva._TotalRecEquiv;
168  if (datosEntregas.HayEntregasDelTipoIva(iva._Codigo))
169  {
170  var infoEntrega = datosEntregas.GetEntregaDelTipoIva(iva._Codigo);
171  baseIva = iva._Base - infoEntrega.Base;
172  totalIva = iva._TotalIva - infoEntrega.ImporteIva;
173  recargoIva = iva._TotalRecEquiv - infoEntrega.ImporteRecargo;
174  }
175 
176  var detalleIva = new DetalleIVATypeCom
177  {
178  BaseImponible = TratarImporte(datosFactura, baseIva, _mascaraParaCertificacion),
179  TipoImpositivo = iva._PrcIva.ToString(_mascaraParaCertificacion),
180  CuotaImpuesto = TratarImporte(datosFactura, totalIva, _mascaraParaCertificacion)
181  };
182  if (iva._PrcRecEquiv != 0 || (iva._Iva0 && datosFactura._oCliente._Recargo))
183  {
184  detalleIva.TipoRecargoEquivalencia = iva._PrcRecEquiv.ToString(_mascaraParaCertificacion);
185  detalleIva.CuotaRecargoEquivalencia = TratarImporte(datosFactura, recargoIva, _mascaraParaCertificacion);
186  }
187  detalleIva.OperacionEnRecargoDeEquivalenciaORegimenSimplificado = "N";
188  detalleIva.OperacionEnRecargoDeEquivalenciaORegimenSimplificadoSpecified = true;
189 
190  return detalleIva;
191  }
192 
193  private SoftwareFacturacionTypeCom Generar_SoftwareFacturacionTypeCom()
194  {
195  SoftwareFacturacionDTO datosSoftware = ObtenerDatosSoftwareFacturacion();
196  var datosSoftwareTypeCom = new SoftwareFacturacionTypeCom()
197  {
198  LicenciaTBAI = datosSoftware.Licencia,
199  EntidadDesarrolladora = new EntidadDesarrolladoraTypeCom()
200  {
201  Item_NIF = datosSoftware.Nif,
202  },
203  Nombre = datosSoftware.Nombre,
204  Version = datosSoftware.Version
205  };
206  return datosSoftwareTypeCom;
207  }
208 
209  private SoftwareFacturacionDTO ObtenerDatosSoftwareFacturacion()
210  {
211  //Task 187743 Centralizado en clase de configuración FACTUCERT
213  //if(ObtenerDatosSoftwareFacturacionDesdeVariables(out SoftwareFacturacionDTO configDTO))
214  //{
215  // return configDTO;
216  //}
217 
219  //SoftwareFacturacionDTO datos = new SoftwareFacturacionDTO
220  //{
221  // Licencia = "TBAIBILVdoPzEpH+JwAJ",
222  // Nif = "B58836321",
223  // Nombre = Convert.ToString(EW_GLOBAL._GetVariable("wc_nameproducto")).Trim(),
224  // Version = sage._50.VersionNumber._Sage50Version.Trim()
225  //};
226  var entorno = GetEntorno();
227  var territorio50 = Convert.ToInt32(GetTerritorioEnvioTBai(false));
228 
229  var datos = FACTUCERT.ObtenerDatosSoftwareFacturacion(entorno, territorio50);
230 
231  return datos;
232  }
233 
242  private bool GenerateTicketBaiDataInternal(string outputFilename, List<ewDocVentaTPV> listaDatosAlbaranes, AsientosFacturasVentaGenerador datosFactura, TicketBai_XML_Parameters XML_generator_parameters)
243  {
244  // Objects of COM model.
245  TicketBaiCom ticketBaiCom = null;
246  GeneratedSignature = "";
247 
248  GenerateTrace("ExportadorFactuCertXML: Entrando en GenerateTicketBaiDataInternal");
249 
250  try
251  {
252  // TicketBai
253  ticketBaiCom = new TicketBaiCom();
254 
255  {
256  // Cabecera
257  ticketBaiCom.Cabecera = new CabeceraCom()
258  {
259  IDVersionTBAI = "1.2"
260  };
261 
262  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando sujeto");
263  // Sujetos
264  ticketBaiCom.Sujetos = new SujetosCom()
265  {
266  // Emisor
267  Emisor = new EmisorCom()
268  {
269  NIF = NormalizarCaracteresNif(((ew.empresa.Empresa)EW_GLOBAL._Empresa)._CifTC),
270  ApellidosNombreRazonSocial = ((ew.empresa.Empresa)EW_GLOBAL._Empresa)._ApellidosTC + " " + ((ew.empresa.Empresa)EW_GLOBAL._Empresa)._NombreTC.Trim()
271  },
272 
273  VariosDestinatarios = "N",
274  VariosDestinatariosSpecified = true,
275  };
276 
277  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Obteniendo datos de C_FACTUVEN");
278  //Obtenemos los datos que necesitamos para rellenar el cuerpo de la factura
279  DataRow facRow = GetRowCompletoTabla("GESTION", "C_FACTUVEN", "EMPRESA = '" + EW_GLOBAL._GetVariable("wc_empresa").ToString() + "' AND NUMERO = '" + XML_generator_parameters.NumDocumentoBorrador + "'");
280 
281  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Comprobando SIITERCERO para datos Sujeto.EmitidaPor");
282  if (Convert.ToBoolean(facRow["SIITERCERO"]))
283  {
284  if (Convert.ToInt32(facRow["TBTERCERO"]) == 1)
285  ticketBaiCom.Sujetos.EmitidaPorTercerosODestinatario = "T";
286  else if (Convert.ToInt32(facRow["TBTERCERO"]) == 2)
287  ticketBaiCom.Sujetos.EmitidaPorTercerosODestinatario = "D";
288  else
289  ticketBaiCom.Sujetos.EmitidaPorTercerosODestinatario = "";
290  }
291  else
292  {
293  ticketBaiCom.Sujetos.EmitidaPorTercerosODestinatario = "N";
294  }
295  ticketBaiCom.Sujetos.EmitidaPorTercerosODestinatarioSpecified = true;
296 
297 
298  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Generando destinatario");
299  // Destinatarios
300  var destinatario = new IDDestinatarioCom();
301 
302  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Obteniendo M_nombre2 de MODCONFI");
303  //171760
304  var resNombre2 = GetValoresTabla(new string[] { "M_nombre2" }, "GESTION", "MODCONFI", "EMPRESA = '" + EW_GLOBAL._GetVariable("wc_empresa").ToString() + "'");
305  if (resNombre2 != null && resNombre2.Length > 0 && Convert.ToInt16(resNombre2[0]) == 1 && !string.IsNullOrWhiteSpace(datosFactura._oCliente._RazonComercial))
306  {
307  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando destinatario con Razon Comercial", "Razon Comercial Factura -> " + datosFactura._oCliente._RazonComercial.Trim());
308  destinatario.ApellidosNombreRazonSocial = datosFactura._oCliente._RazonComercial.Trim();
309  }
310  else
311  {
312  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando destinatario con Nombre", "Nombre Factura -> " + datosFactura._oCliente._Nombre.Trim());
313  destinatario.ApellidosNombreRazonSocial = datosFactura._oCliente._Nombre.Trim();
314  }
315 
316  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando Codigo Postal");
317  destinatario.CodigoPostal = string.IsNullOrWhiteSpace(listaDatosAlbaranes.First()._Cabecera._DatosContado._CodPost) ? datosFactura._oCliente._CodPost.Trim() : listaDatosAlbaranes.First()._Cabecera._DatosContado._CodPost.Trim();
318  //Nuevo v.1.2 Direccion
319  destinatario.Direccion = string.IsNullOrWhiteSpace(listaDatosAlbaranes.First()._Cabecera._DatosContado._Direccion) ? datosFactura._oCliente._Direccion.Trim() : listaDatosAlbaranes.First()._Cabecera._DatosContado._Direccion.Trim();
320 
321  //ID
322  //171653
323  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando ID. Buscamos Id_Fiscal");
324  var resModidfis = GetValoresTabla(new string[] { "Id_Fiscal" }, "GESTION", "MODIDFIS", "CUENTA = '" + datosFactura._oCliente._Codigo + "'");
325  int idFiscal = (resModidfis != null && resModidfis.Length > 0) ? Convert.ToInt32(resModidfis[0]) : 0;
326  if (idFiscal == 1 || idFiscal == 0 || idFiscal == 7)
327  {
328  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Id_Fiscal Nif o similar");
329  destinatario.Item_NIF = string.IsNullOrWhiteSpace(datosFactura._oCliente._NIF) ? "" : NormalizarCaracteresNif(datosFactura._oCliente._NIF);
330  }
331  else
332  {
333  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Id_Fiscal Extranjero");
334  try
335  {
336  var paisCliente = GetValoresTabla(new string[] { "Letra" }, "COMUNES", "PAISES", "CODIGO = '" + datosFactura._oCliente._Pais + "'");
337 
338  var codigoPais = paisCliente[0].ToString().ToUpper().Trim();
339 
340  //Bug 196957 => Capamos el envio de códigos numericos hacia el componente pq los convierte en un acceso por índice contra su enumerado de paises
341  if (codigoPais.__IsNumber())
342  {
343  ErrorMessage = $"El pais con código {datosFactura._oCliente._Pais} tiene por sigla {codigoPais} y no pueden ser un número. Revise la codificación del país.";
344  return false;
345  }
346 
347  var nifCliente = string.IsNullOrWhiteSpace(datosFactura._oCliente._NIF) ? "" : NormalizarCaracteresNif(datosFactura._oCliente._NIF);
348  if (idFiscal == 2)
349  {
350  nifCliente = FUNCTIONS.IncorporarPaisAlNif(codigoPais, nifCliente);
351  }
352 
353  destinatario.Item_IDOtro = new IDOtroCom()
354  {
355  CodigoPais = codigoPais,
356  CodigoPaisSpecified = true,
357  IDType = "Item0" + idFiscal.ToString().Trim(),
358  ID = nifCliente
359  };
360  }
361  catch
362  {
363  throw new NotSupportedException("Es necesario informar código de país para la cuenta de cliente " + datosFactura._oCliente._Codigo + " debido al tipo de identificación fiscal que tiene asignado. Revise el país y tipo de identificación fiscal del cliente.");
364  }
365  }
366 
367  //172900
368  bool tieneConsideracionDeSimplificada = false;
369  if (Convert.ToBoolean(facRow["SIIF1NOID"]) ||
370  (facRow["SIINUMINI"] != null && facRow["SIINUMINI"] != DBNull.Value && !string.IsNullOrWhiteSpace(facRow["SIINUMINI"].ToString()) && facRow["SIINUMFIN"] != null && facRow["SIINUMFIN"] != DBNull.Value && !string.IsNullOrWhiteSpace(facRow["SIINUMFIN"].ToString()) && facRow["SIINUMINI"].ToString() == facRow["SIINUMFIN"].ToString()) ||
371  (string.IsNullOrWhiteSpace(datosFactura._oCliente._NIF)))
372  {
373  tieneConsideracionDeSimplificada = true;
374  }
375 
376  if (!tieneConsideracionDeSimplificada)
377  ticketBaiCom.Sujetos.Destinatarios = new IDDestinatarioCom[] { destinatario };
378 
379  //172398
380  //GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Obtenemos datos de tabla FCFACTUVEN", "Params: " + EW_GLOBAL._GetVariable("wc_empresa").ToString() + " / " + EW_GLOBAL._GetVariable("wc_any").ToString().Trim() + " / " + XML_generator_parameters.NumDocumentoBorrador);
381  //DataRow fcFacturaRow = GetRowCompletoTabla(FACTUCERT._NombreAddOn, "FCFACTUVEN", "EMPRESA = '" + EW_GLOBAL._GetVariable("wc_empresa").ToString() + "' AND EJERCICIO = '" + EW_GLOBAL._GetVariable("wc_any").ToString().Trim() + "' AND NUMERO = '" + XML_generator_parameters.NumDocumentoBorrador + "'");
382  //GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Resultado consulta FCFACTUVEN -> " + (fcFacturaRow != null).ToString());
383  //if (fcFacturaRow == null)
384  // throw new Exception("No ha podido leerse correctamente la información de Factura Certificada del documento " + XML_generator_parameters.NumDocumentoBorrador);
385  ticketBaiCom.Sujetos.Emisor.Territorio = GetTerritorioEnvioTBai(true);//172398
386 
387  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Generando la cabecera de la Factura");
388 
389  //174296
390  string serieFac = datosFactura._Factura.Substring(0, 2).Trim();
391  string numFac = datosFactura._Factura.Substring(2).Trim();
392 
393  if (!string.IsNullOrWhiteSpace((string)(facRow["SIIFRAMOD"])))
394  {
395  serieFac = "";
396  if (facRow["SIIFRAMOD"].ToString().Trim().Length > 20)
397  numFac = facRow["SIIFRAMOD"].ToString().Trim().Substring(0, 20);
398  else
399  numFac = facRow["SIIFRAMOD"].ToString().Trim();
400  }
401  else if (Convert.ToInt32(facRow["OPERACION"]) == 12 && !string.IsNullOrWhiteSpace((string)(facRow["SIINUMDER"])))
402  {
403  serieFac = "";
404  numFac = facRow["SIINUMDER"].ToString().Trim();
405  }
406 
407  // Factura
408 
409  ticketBaiCom.Factura = new FacturaCom()
410  {
411  // Cabecera factura
412  CabeceraFactura = new ComModel.Invoice.V1_0.CabeceraFacturaTypeCom()
413  {
414  SerieFactura = serieFac,
415  NumFactura = numFac,
416  FechaExpedicionFactura = datosFactura._Fecha.ToString("dd-MM-yyyy"),
417  HoraExpedicionFactura = XML_generator_parameters.HoraCertificacion?.Trim(),
418  FacturaSimplificada = tieneConsideracionDeSimplificada ? "S" : "N",
419  FacturaSimplificadaSpecified = true,
420  FacturaEmitidaSustitucionSimplificada = Convert.ToInt32(facRow["OPERACION"]) == 28 ? "S" : "N",
421  FacturaEmitidaSustitucionSimplificadaSpecified = true
422  }
423  };
424 
425  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Viendo si es rectificativa a partir de SIIORIMOT");
426  // Factura rectificativa
427  if (facRow["SIIORIMOT"] != null && facRow["SIIORIMOT"] != DBNull.Value && !string.IsNullOrWhiteSpace(facRow["SIIORIMOT"].ToString()))
428  {
429  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Es rectificativa, rellenamos datos");
430  ticketBaiCom.Factura.CabeceraFactura.FacturaRectificativa = new FacturaRectificativaTypeCom()
431  {
432  Codigo = facRow["SIIORIMOT"]?.ToString().Trim(),
433  Tipo = facRow["SIIORITIP"]?.ToString().Trim(),
434  };
435 
436  // Importe factura rectificativa
437  //177950
438  if (Convert.ToString(facRow["SIIORITIP"]) == "S")
439  {
440  ticketBaiCom.Factura.CabeceraFactura.FacturaRectificativa.ImporteRectificacionSustitutiva = new ImporteRectificacionSustitutivaTypeCom()
441  {
442  BaseRectificada = Convert.ToDecimal(facRow["SIIORIBAS"]).ToString(_mascaraParaCertificacion).Trim(),
443  CuotaRectificada = Convert.ToDecimal(facRow["SIIORIIVA"]).ToString(_mascaraParaCertificacion).Trim(),
444  CuotaRecargoRectificada = Convert.ToDecimal(facRow["SIIORIREC"]).ToString(_mascaraParaCertificacion).Trim(),
445  };
446  }
447  }
448  else //Miro si es tipo 11 que tambien necesita FacturaRectificativaTypeCom
449  {
450  if (Convert.ToInt32(facRow["OPERACION"]) == 11) //Task 187717 - Modificación factura inicial / Certificaciones obra AAPP
451  {
452  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Es Modificación factura inicial / Certificaciones obra AAPP, rellenamos datos");
453  ticketBaiCom.Factura.CabeceraFactura.FacturaRectificativa = new FacturaRectificativaTypeCom()
454  {
455  Codigo = "R4",
456  Tipo = "S",
457  };
458 
459  ticketBaiCom.Factura.CabeceraFactura.FacturaRectificativa.ImporteRectificacionSustitutiva = new ImporteRectificacionSustitutivaTypeCom()
460  {
461  BaseRectificada = Convert.ToDecimal(facRow["SIIDEVBAS"]).ToString(_mascaraParaCertificacion).Trim(),
462  CuotaRectificada = Convert.ToDecimal(facRow["SIIDEVCUO"]).ToString(_mascaraParaCertificacion).Trim(),
463  CuotaRecargoRectificada = Convert.ToDecimal(facRow["SIIDEVREC"]).ToString(_mascaraParaCertificacion).Trim(),
464  };
465  }
466  }
467 
468  if (Convert.ToString(facRow["SIIORICAN"]) == "2")
469  {
470  //Rectificativa múltiple
471  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Datos facturas sustituidas a partir de D_FACTURECT");
472 
473  //Recuperar los datos
474 
475  List<IDFacturaRectificadaSustituidaTypeCom> lstSustituidas = new List<IDFacturaRectificadaSustituidaTypeCom>();
476 
477  decimal baseRectificada = decimal.Zero; //Campos para acumular
478  decimal cuotaRectificada = decimal.Zero;
479  decimal cuotaRecargoRectificada = decimal.Zero;
480  foreach (DetalleFacturaRectificativaDTO fraRectificada in ObtenerDatosRectificadasMultiplesFacturas(XML_generator_parameters.NumDocumentoBorrador))
481  {
482  //Actualizo el importe acumulado de la rectificación
483  baseRectificada += fraRectificada.Base_iva;
484  cuotaRectificada += fraRectificada.Iva;
485  cuotaRecargoRectificada += fraRectificada.Recargo;
486 
487  var fraSustituida = new IDFacturaRectificadaSustituidaTypeCom
488  {
489  SerieFactura = fraRectificada.Factu_rect.Substring(0, 2),
490  NumFactura = fraRectificada.Factu_rect.Substring(2),
491  FechaExpedicionFactura = fraRectificada.Fecha.ToString("dd-MM-yyyy")
492  };
493  lstSustituidas.Add(fraSustituida);
494  }
495 
496  ticketBaiCom.Factura.CabeceraFactura.FacturaRectificativa.ImporteRectificacionSustitutiva = new ImporteRectificacionSustitutivaTypeCom()
497  {
498  BaseRectificada = baseRectificada.ToString(_mascaraParaTicketBAI).Trim(),
499  CuotaRectificada = cuotaRectificada.ToString(_mascaraParaTicketBAI).Trim(),
500  CuotaRecargoRectificada = cuotaRecargoRectificada.ToString(_mascaraParaTicketBAI).Trim(),
501  };
502 
503  ticketBaiCom.Factura.CabeceraFactura.FacturasRectificadasSustituidas = lstSustituidas.ToArray();
504  }
505  else
506  {
507  //TFS 104842/172901/179552
508  if (Convert.ToInt32(facRow["OPERACION"]) != 28 && Convert.ToInt32(facRow["OPERACION"]) != 11) //28 => Fra. Emitida en sustitución fra. Simplificada sin ident.
509  {
510  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Datos facturas sustituidas a partir de SIIORIFRA");
511  // Identificadores facturas rectificadas sustituidas.
512  if (facRow["SIIORIFRA"] != null && facRow["SIIORIFRA"] != DBNull.Value && !string.IsNullOrWhiteSpace(facRow["SIIORIFRA"].ToString()))
513  {
514  ticketBaiCom.Factura.CabeceraFactura.FacturasRectificadasSustituidas = new IDFacturaRectificadaSustituidaTypeCom[]
515  {
516  new IDFacturaRectificadaSustituidaTypeCom
517  {
518  SerieFactura = facRow["SIIORIFRA"].ToString().Substring(0, 2).Trim(), //Se ha comprobado SIIORIFRA no sea null antes de entrar aqui
519  NumFactura = facRow["SIIORIFRA"].ToString().Substring(2).Trim(),
520  FechaExpedicionFactura = (facRow["SIIORIFEC"] != null && facRow["SIIORIFEC"] != DBNull.Value) ? ((DateTime)facRow["SIIORIFEC"]).ToString("dd-MM-yyyy") : "",
521  },
522  };
523  }
524  }
525  else
526  {
527  //Task 187717 - Modificación factura inicial / Certificaciones obra AAPP (op.11) => Rellena igual los campos, aprovecho el bloque
528 
529  // Identificadores facturas rectificadas sustituidas.
530  if (facRow["SIIDEVFRA"] != null && facRow["SIIDEVFRA"] != DBNull.Value && !string.IsNullOrWhiteSpace(facRow["SIIDEVFRA"].ToString()))
531  {
532  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Datos facturas sustituidas a partir de SIIDEVFRA");
533 
534  ticketBaiCom.Factura.CabeceraFactura.FacturasRectificadasSustituidas = new IDFacturaRectificadaSustituidaTypeCom[]
535  {
536  new IDFacturaRectificadaSustituidaTypeCom
537  {
538  SerieFactura = facRow["SIIDEVFRA"].ToString().Substring(0, 2).Trim(), //Se ha comprobado SIIDEVFRA no sea null antes de entrar aqui
539  NumFactura = facRow["SIIDEVFRA"].ToString().Substring(2).Trim(),
540  FechaExpedicionFactura = (facRow["SIIDEVFEC"] != null && facRow["SIIDEVFEC"] != DBNull.Value) ? ((DateTime)facRow["SIIDEVFEC"]).ToString("dd-MM-yyyy") : "",
541  },
542  };
543  }
544  }
545  }
546 
547 
548  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Generando el cuerpo de la Factura");
549  // Datos factura
550 
551  //Task 200300
552  EntregasEnFactura datosEntregas = new EntregasEnFactura(datosFactura);
553 
554  ticketBaiCom.Factura.DatosFactura = new DatosFacturaTypeCom()
555  {
556  FechaOperacion = datosFactura._Fecha_Operacion.ToString("dd-MM-yyyy"),
557  DescripcionFactura = string.IsNullOrWhiteSpace(listaDatosAlbaranes.First()._Cabecera._DescFac) ? "N/FRA " + datosFactura._Factura.Trim() + " " + datosFactura._Nombre.Trim() : listaDatosAlbaranes.First()._Cabecera._DescFac.Trim(),
558  // Identificadores detalle factura
559 
560  //172902
561  ImporteTotalFactura = TratarImporte(datosFactura, GetImporteTotalFactura(datosFactura, datosEntregas), _mascaraParaCertificacion),
562  RetencionSoportada = TratarImporte(datosFactura, GetImporteRetencionFiscal(datosFactura), _mascaraParaCertificacion),
563  //BaseImponibleACoste = "", // si diera guerra poner 0.00
564  };
565 
566  //153558
567  if (facRow["SIIORIFOP"] != null && facRow["SIIORIFOP"] != DBNull.Value)
568  {
569  ticketBaiCom.Factura.DatosFactura.FechaOperacion = Convert.ToDateTime(facRow["SIIORIFOP"]).ToString("dd-MM-yyyy");
570  //179230: Por un error de S50 el campo SIIDEVFOP lo están rellenando incluso cuando NO es factura rectificativa sustitutiva
571  //Lo controlamos aquí para no tener que estar pendientes de cuándo se solucione en el negocio del core
572  }
573  else
574  {
575  if (Convert.ToInt32(facRow["OPERACION"]) == 28 && facRow["SIIDEVFOP"] != null && facRow["SIIDEVFOP"] != DBNull.Value)
576  ticketBaiCom.Factura.DatosFactura.FechaOperacion = Convert.ToDateTime(facRow["SIIDEVFOP"]).ToString("dd-MM-yyyy");
577  }
578 
579  var lineaDetalleIncluidas = new List<IDDetalleFacturaTypeCom>();
580 
581  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Generando las líneas a partir de los Albaranes");
582  //Detalles de albaranes
583  foreach (var albaran in listaDatosAlbaranes)
584  {
585  //CCR 199730
586  var hayPuntoVerde = Convert.ToBoolean(EW_GLOBAL._GetVariable("wl_pverde")) && !albaran._Cabecera._oCliente._NoApli_Impuesto_Artic;
587 
588 #if SuplidosDtosPortes
589  //Task 185731 => Suprimir líneas de suplidos
590  var lineasAlbaran = albaran._Lineas.Where(l => l._Suplido.Equals(false)).ToList(); //Eliminar suplidos
591  foreach (var linea in lineasAlbaran)
592 #else
593  foreach (var linea in albaran._Lineas)
594 #endif
595  {
596  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Procesando línea albarán " + albaran._Numero + "-" + linea._Linea);
597 
598  //178258
599  //if (linea._Unidades != 0 && linea._Precio != 0)
600  //Hablado con Conchi, para discriminar las lineas de comentario saltamos las que tienen tipo de IVA <> ""
601  if (!string.IsNullOrWhiteSpace(linea._TipoIva))
602  {
603  var lineaAlb = new IDDetalleFacturaTypeCom
604  {
605  DescripcionDetalle = linea._Definicion.Trim(),
606  ImporteUnitario = linea._Precio.ToString(_mascara8decimales),
607  };
608 
609  //Bug 191918 => Para tarifas IVA Incluido no lo tiene incluido. Afino la condición y restauro el bloque de código original
612  if (datosFactura._IvaIncluido && datosFactura._oCliente._Recargo)
613  {
614  decimal importeConRecargo = linea._ImporteIva;
615  decimal porcentajeRecargo = datosFactura._TipoIvaLineas.Where(TI => TI._Codigo == linea._TipoIva).Select(TI => TI._PrcRecEquiv).FirstOrDefault();
616  importeConRecargo += (linea._Importe * porcentajeRecargo / 100m);//179231
617 
618  lineaAlb.ImporteTotal = importeConRecargo.ToString(GetMascaraEspecificaPorTerritorio("ImporteTotal", _mascaraParaCertificacion));
619  }
620  else
621  {
622  lineaAlb.ImporteTotal = linea._ImporteIva.ToString(GetMascaraEspecificaPorTerritorio("ImporteTotal", _mascaraParaCertificacion));
623  }
624 
625  //104842/172899
626  /*
627  1.- SI D_ALBVEN.TIPOPREC =0 o D_ALBVEN.TIPOPREC=2 ENTONCES:
628  ---- - Si D_ALBVEN.PESO <> 0 INFORMAR DICHO VALOR DEL CAMPO D_ALBVEN.PESO
629  ---- - Si D_ALBVEN.PESO = 0 INFORMAR EL VALOR DEL CAMPO D_ALBVEN.UNIDADES
630  2.- SI D_ALBVEN.TIPOPREC = 1 ENTONCES INFORMAR EL VALOR DEL CAMPO D_ALBVEN.CAJAS
631  3.- SI D_ALBVEN.TIPOPREC = 3 ENTONCES:
632  ---- - Si D_ALBVEN.PESO <> 0 INFORMAR DICHO VALOR DEL CAMPO D_ALBVEN.PESO / 1000
633  ---- - Si D_ALBVEN.PESO = 0 INFORMAR EL VALOR DEL CAMPO D_ALBVEN.UNIDADES / 1000
634  */
635  decimal cantidad;
636  switch (linea._TipoPrec)
637  {
638  case 0:
639  case 2:
640  if (linea._Peso != 0)
641  cantidad = linea._Peso;
642  else
643  cantidad = linea._Unidades;
644  break;
645  case 1:
646  cantidad = linea._Cajas;
647  break;
648  case 3:
649  if (linea._Peso != 0)
650  cantidad = linea._Peso / 1000m;
651  else
652  cantidad = linea._Unidades / 1000m;
653  break;
654  default:
655  //Por aqui no deberia entrar
656  throw new NotSupportedException("El tipo de precio de la línea no está soportado");
657  }
658  lineaAlb.Cantidad = cantidad.ToString(GetMascaraEspecificaPorTerritorio("Cantidad", _mascaraParaCertificacion));
659  //182286
660  if (linea._Dto1 != 0 || linea._Dto2 != 0)
661  lineaAlb.Descuento = ((cantidad * linea._Precio) - linea._Importe).ToString(GetMascaraEspecificaPorTerritorio("Descuento", _mascaraParaCertificacion));
662  else
663  lineaAlb.Descuento = 0.ToString(GetMascaraEspecificaPorTerritorio("Descuento", _mascaraParaCertificacion));
664 
665 #if SuplidosDtosPortes
666  lineaDetalleIncluidas.Add(lineaAlb); //Task 185731 => No inserto todavía pq necesito las líneas para cálculos posteriores
667 #else
668  ticketBaiCom.Factura.DatosFactura.AddDetalleFactura(lineaAlb);
669 #endif
670 
671  if (hayPuntoVerde && !linea._PuntoVerde.Equals(decimal.Zero) && !cantidad.Equals(decimal.Zero))
672  {
673  var literalPVerde = ((ew.empresa.Empresa)EW_GLOBAL._Empresa)._TituloImpuestoArticulo.TrimEnd();
674 
675  var lineaPVerde = new IDDetalleFacturaTypeCom
676  {
677  DescripcionDetalle = literalPVerde,
678  Cantidad = (1).ToString(_mascara8decimales),
679  ImporteUnitario = linea._PuntoVerde.ToString(_mascara8decimales),
680  };
681 
682  decimal porcentajeIva = datosFactura._TipoIvaLineas.Where(TI => TI._Codigo == linea._TipoIva).Select(TI => TI._PrcIva).FirstOrDefault();
683  decimal importeDelPuntoVerde = (linea._PuntoVerde * (1 + (porcentajeIva / 100m))); //Añado el IVA
684 
685  if (datosFactura._oCliente._Recargo)
686  {
687  decimal porcentajeRecargo = datosFactura._TipoIvaLineas.Where(TI => TI._Codigo == linea._TipoIva).Select(TI => TI._PrcRecEquiv).FirstOrDefault();
688  importeDelPuntoVerde += (linea._PuntoVerde * porcentajeRecargo / 100m); //Añado el recargo
689  }
690 
691  lineaPVerde.ImporteTotal = (importeDelPuntoVerde).ToString(GetMascaraEspecificaPorTerritorio("ImporteTotal", _mascaraParaCertificacion));
692 
693 #if SuplidosDtosPortes
694  lineaDetalleIncluidas.Add(lineaPVerde); //No inserto todavía pq necesito las líneas para cálculos posteriores
695 #else
696  ticketBaiCom.Factura.DatosFactura.AddDetalleFactura(lineaPVerde);
697 #endif
698  }
699  }
700 
701  }
702 
703 #if SuplidosDtosPortes
704  //Task 185731 => Líneas de portes
705  #region Portes
706 
707  var portes = albaran._Pie._Portes;
708  if (portes != null && !portes._Importe.Equals(decimal.Zero))
709  {
710  var importeUnitario = decimal.Zero;
711  var importeTotal = decimal.Zero;
712  ew.articulo.TipoIVA tipoIva = new ew.articulo.TipoIVA
713  {
714  _Codigo = portes._Tipo_Iva
715  };
716 
717 
718  if (portes._Iva_Incluido)
719  {
720  //IMPORTE UNITARIO= si PORTES.IVA_INC=.T. IMPORTE UNITARIO=PORTES.IMPORTE/(1+TIPO_IVA.IVA que corresponda al codigo PORTES.TIPO_IVA)
721  importeUnitario = portes._Importe / ((100 + tipoIva._IVA) / 100);
722  importeTotal = portes._Importe;
723  }
724  else
725  {
726  //IMPORTE UNITARIO=PORTES.IMPORTE si PORTES.IVA_INC=.F.
727  importeUnitario = portes._Importe;
728  //IMPORTE TOTAL = PORTES.IMPORTE * (1 + TIPO_IVA.IVA que corresponda al codigo PORTES.TIPO_IVA) si PORTES.IVA_INC =.F.
729  importeTotal = portes._Importe * ((100 + tipoIva._IVA) /100) ; //TratarImporte(datosFactura, iva._TotalRecEquiv, _mascaraParaTicketBAI)
730  }
731 
732  //Bug 189366 => Añadir recargo (sobre el importe sin IVA de los portes)
733  if (datosFactura._oCliente._Recargo)
734  importeTotal += importeUnitario * (tipoIva._Recargo / 100);
735 
736  var lineaPortes = new IDDetalleFacturaTypeCom
737  {
738  DescripcionDetalle = "PORTES",
739  ImporteUnitario = importeUnitario.ToString(_mascara8decimales),
740  Cantidad = 1d.ToString(GetMascaraEspecificaPorTerritorio("Cantidad", _mascaraParaCertificacion)),
741  Descuento = decimal.Zero.ToString(GetMascaraEspecificaPorTerritorio("Descuento", _mascaraParaCertificacion)),
742  ImporteTotal = importeTotal.ToString(GetMascaraEspecificaPorTerritorio("ImporteTotal", _mascaraParaCertificacion)),
743  };
744  lineaDetalleIncluidas.Add(lineaPortes);
745  tipoIva = null;
746  }
747 
748  #endregion Portes
749 
750 
751 #endif
752  }
753 
754  //Task 185731 => Línea de pronto pago
755  #region Pronto Pago
756 
757  //En facturas de múltiples albaranes se agrupan las que tienen el mismo DtoPP, sólo que detecte uno el resto también tendra y con el mismo %
758  var hayDtoProntoPago = listaDatosAlbaranes.Any(alb => !(alb._Pie._DtoPP.Equals(decimal.Zero)));
759  if (hayDtoProntoPago)
760  {
761  var importeUnitario = decimal.Zero;
762  var importeTotal = decimal.Zero;
763 
764  //IMPORTE UNITARIO = Sumatorio de bases imponibles (operaciones Sujetas)+sumatorio Importes (Operaciones no sujetas) que se llevarán al XML
765  // -[Sumatorio de cantidad *Importe unitario-Descuentos de cada uno de los detalles].
766  var importesNoSujetos = decimal.Zero;
767  var importesSujetos = decimal.Zero;
768  var importeDetalle = decimal.Zero;
769  foreach (var iva in datosFactura._TipoIvaLineas)
770  {
771  if (EsSujeta(ObtenerTipoOperacionFactura(XML_generator_parameters.NumDocumentoBorrador, iva._Codigo)))
772  {
773  importesSujetos += iva._Base; //No convertir en divisa, se hace al final
774  }
775  else
776  {
777  importesNoSujetos += iva._Base + iva._TotalIva;
778  }
779  }
780  importeDetalle = lineaDetalleIncluidas.Sum(ld => ((_DeTextoADecimal(ld.Cantidad) * _DeTextoADecimal(ld.ImporteUnitario)) - _DeTextoADecimal(ld.Descuento)));
781  importeUnitario = ToMonedaEmpresa(datosFactura, (importesNoSujetos + importesSujetos)) - importeDetalle; //Detalle en moneda empresa importes en divisa => Convierto
782 
783  //IMPORTE TOTAL = ImporteTotalFactura - Sumarorio del Importe Total linea de cada detalle
784  var impoteTotalDetallesIncluidos = lineaDetalleIncluidas.Sum(ld => _DeTextoADecimal(ld.ImporteTotal));
785 
786  importeTotal = (ToMonedaEmpresa(datosFactura, GetImporteTotalFactura(datosFactura, datosEntregas)) - impoteTotalDetallesIncluidos); //Detalle en moneda empresa y Totales en divisa => Convierto
787 
788  if (!importeTotal.Equals(decimal.Zero) || !importeUnitario.Equals(decimal.Zero)) //Bug 186206 => Si ambos importes son 0 no inserto nada
789  {
790  var lineaProntoPago = new IDDetalleFacturaTypeCom
791  {
792  DescripcionDetalle = "DESCUENTO PRONTO PAGO",
793  ImporteUnitario = importeUnitario.ToString(_mascara8decimales), //Ya esta en moneda empresa
794  Cantidad = 1d.ToString(GetMascaraEspecificaPorTerritorio("Cantidad", _mascaraParaCertificacion)),
795  Descuento = decimal.Zero.ToString(GetMascaraEspecificaPorTerritorio("Descuento", _mascaraParaCertificacion)),
796  ImporteTotal = importeTotal.ToString(GetMascaraEspecificaPorTerritorio("ImporteTotal", _mascaraParaCertificacion)) //Ya esta en moneda empresa
797  };
798  lineaDetalleIncluidas.Add(lineaProntoPago);
799  }
800  }
801 
802  #endregion Pronto Pago
803 
804  //Task 200300
805  #region Entregas a cuenta
806 
807  //Primero miramos si la instalación admite entregas a cuenta y tenemos alguna en la ficha
808  if (datosEntregas.HayEntregasAplicadas)
809  {
810  //Generamos una linea por cada detalle de entrega (que viene agrupada por tipo de iva) en factura
811  foreach (EntregasEnFactura.EntregaEnFactura entrega in datosEntregas.Entregas)
812  {
813  var lineaEntrega = new IDDetalleFacturaTypeCom
814  {
815  DescripcionDetalle = $"ANTICIPO DESCONTADO TIPO IVA {entrega.CodigoIva}",
816  Cantidad = 1d.ToString(GetMascaraEspecificaPorTerritorio("Cantidad", _mascaraParaCertificacion)),
817  ImporteUnitario = (-1 * entrega.Base).ToString(_mascara8decimales), //Ya esta en moneda empresa
818  Descuento = decimal.Zero.ToString(GetMascaraEspecificaPorTerritorio("Descuento", _mascaraParaCertificacion)),
819  ImporteTotal = (-1 * entrega.Importe).ToString(GetMascaraEspecificaPorTerritorio("ImporteTotal", _mascaraParaCertificacion)) //Ya esta en moneda empresa
820  };
821  lineaDetalleIncluidas.Add(lineaEntrega);
822  }
823  }
824 
825  #endregion Entregas a cuenta
826 
827  //Validamos si excede el número de lineas detalle máximo (1000)
828  if (lineaDetalleIncluidas.Count > 1000)
829  {
830  ErrorMessage = "Imposible certificar la factura. " + Environment.NewLine + Environment.NewLine +
831  "Se ha superado el número máximo de líneas de 1000, admitido para el envío a la Hacienda Foral. " + Environment.NewLine +
832  "Además de las líneas indicadas en el documento, se añaden líneas automáticas con portes, descuentos y ecotasas. " +
833  "Por favor, revise la factura para dividirla en varias. ";
834  return false;
835  }
836 
837  //Añadimos todos los detalles
838  lineaDetalleIncluidas.ForEach(ld => ticketBaiCom.Factura.DatosFactura.AddDetalleFactura(ld));
839 
840  #region Identificando Regimen Especial Trascendencia
841 
842  // Identificadores de clave
843  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Identificando Regimen Especial Trascendencia");
844  GenerarClaveRegimenEspecialTrascendencia(facRow, XML_generator_parameters,
845  _nTerritorio: 1, //1 es Territorio Común de SII
846  lnComuni_c: Convert.ToInt32(datosFactura._oCliente._TipoCliente),
847  lcNif: NormalizarCaracteresNif(datosFactura._oCliente._NIF),
848  llCritCaja: datosFactura._Recc,
849  llIvaNoCero: datosFactura._TipoIvaLineas[0]._PrcIva > 0,
850  ClaveRegimenEspecialOTrascendencia: out string ClaveRegimenIvaOpTrascendencia,
851  ClaveRegimenEspecialOTrascendenciaAdicional1: out string ClaveRegimenIvaOpTrascendenciaAdicional);
852  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Resultado Regimen Especial Trascendencia " + ClaveRegimenIvaOpTrascendencia.ToString());
853  if (string.IsNullOrWhiteSpace(ClaveRegimenIvaOpTrascendenciaAdicional))
854  {
855  ticketBaiCom.Factura.DatosFactura.Claves = new IDClaveTypeCom[]
856  {
857  new IDClaveTypeCom()
858  {
859  ClaveRegimenIvaOpTrascendencia = "Item" + ClaveRegimenIvaOpTrascendencia.Trim()
860  },
861  };
862  }
863  else
864  {
865  ticketBaiCom.Factura.DatosFactura.Claves = new IDClaveTypeCom[]
866  {
867  new IDClaveTypeCom()
868  {
869  ClaveRegimenIvaOpTrascendencia = "Item" + ClaveRegimenIvaOpTrascendencia.Trim()
870  },
871  new IDClaveTypeCom()
872  {
873  ClaveRegimenIvaOpTrascendencia = "Item" + ClaveRegimenIvaOpTrascendenciaAdicional.Trim()
874  },
875  };
876  }
877 
878  #endregion Identificando Regimen Especial Trascendencia
879 
880  //171770
881  bool RecargoFinancieroPendienteDeDescontar = datosFactura._TotalRecFinan != 0;
882 
883  // Tipo desglose
884  ticketBaiCom.Factura.TipoDesglose = new TipoDesgloseTypeCom();
885 
886  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Procesando Lineas de IVA Factura");
887 
888  //181416: Si se ha rellenado el IDOtro, solo el hecho de acceder a Item_NIF da una excepcion en el componente. Salvamos el caso con un try/catch
889  string nifCli = "";
890  try
891  {
892  nifCli = destinatario.Item_NIF;
893  nifCli = NormalizarCaracteresNif(nifCli);
894  }
895  catch
896  {
897  try
898  {
899  nifCli = destinatario.Item_IDOtro.ID;
900  }
901  catch { }
902  }
903 
904  var lnOperacion = Convert.ToInt16(facRow["operacion"]);
905 
906  string TipoNoExenta = ""; //Se ha de contemplar que puedan venir distintos tipos
907 
908  bool bloqueSIIEXENTAinsertado = false; //Bug 200085 => Este bloque se crea a nivel de datos de registro de factura, no hay que duplicarlo
909 
910  bool tratamientoRebu = lnOperacion.Equals(15) && datosFactura._TipoIvaLineas.Count == 2 && datosFactura._TipoIvaLineas.Count(i => i._Iva0).Equals(1);
911 
912  foreach (var iva in datosFactura._TipoIvaLineas)
913  {
914  if (tratamientoRebu && iva._Iva0) //En tratamiento REBU sólo se consigna registro de IVA distinto de 0%
915  {
916  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Omitiendo registro para IVA " + iva._Codigo + " (iva 0%) en tratamiento REBU ");
917  continue;
918  }
919 
920  eTipoOperacionEmitidasSII tipoOpIva = ObtenerTipoOperacionFactura(XML_generator_parameters.NumDocumentoBorrador, iva._Codigo);
921  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: TipoOperacionSII obtenido para IVA " + iva._Codigo + " -> " + tipoOpIva.ToString());
922 
923  //Task 185108 => Incorporar casos especiales del SII
924  var lnComuni_c = Convert.ToInt32(datosFactura._oCliente._TipoCliente);
925  var comunitario = (lnComuni_c == 2);
926  var extracomunitario = (lnComuni_c == 3);
927  var llIvaNoCero = iva._PrcIva > 0;
928  var ivaPrestacionDeServicios = ObtenerSiiIva303(XML_generator_parameters.NumDocumentoBorrador, "DEV_IS", iva._Codigo); //Iva de prestacion de servicios
929  var llTratamientoNacinal = (nifCli.StartsWith("N") || lnComuni_c == 2 || lnComuni_c == 3) && (llIvaNoCero || ivaPrestacionDeServicios); //Task 186340 => Nifs W no forzamos
930 
931  #region Evaluar condiciones IVA EUROPEO
932 
933  //Evaluar condiciones IVA EUROPEO
934  var IvaEuropeoConDesgloseOperacion = false;
935  var IvaEuropeoConDesgloseFactura = false;
936  var noEsClienteNacional = (nifCli.StartsWith("N") || lnComuni_c == 2 || lnComuni_c == 3); //Task 186340 => Nifs W no forzamos
937  var clienteNacional = !noEsClienteNacional;
938  var facturaSinIdentificaciónDelDestinatario = Convert.ToBoolean(facRow["SIIF1NOID"]);
939  var destinatarioIdentificado = !facturaSinIdentificaciónDelDestinatario;
940 
941  var IvaServicioSujeto = ivaPrestacionDeServicios && EsSujeta(tipoOpIva);
942  var IvaServicioNoSujeto = ivaPrestacionDeServicios && EsNoSujeta(tipoOpIva);
943  var IvaNoServicioSujeto = !ivaPrestacionDeServicios && EsSujeta(tipoOpIva);
944  var IvaNoServicioNoSujeto = !ivaPrestacionDeServicios && EsNoSujeta(tipoOpIva);
945 
946  //Si el tipo de operación es C_FACTUVEN.Operacion = 32, 33 o 35 y el cliente NO es Nacional y tipo_iva de la línea es Servicio y No sujeto(tipo_iva.inmovil=.T.y tipo_iva.exento=.T.)
947  var IvaEuropeoDesgloseOperacion_ServioNoSujeto = (lnOperacion == 32 || lnOperacion == 33 || lnOperacion == 35) && noEsClienteNacional && IvaServicioNoSujeto;
948 
949  //Si el tipo de operación es C_FACTUVEN .Operacion = 32, 34 o 35 y el cliente NO es Nacional y tipo_iva de la línea es NO Servicio y No sujeto(tipo_iva.inmovil =.F.y tipo_iva.exento =.T.)
950  var IvaEuropeoDesgloseOperacion_NoServicioNoSujeto = (lnOperacion == 32 || lnOperacion == 34 || lnOperacion == 35) && noEsClienteNacional && destinatarioIdentificado && IvaNoServicioNoSujeto;
951 
952  IvaEuropeoConDesgloseOperacion = IvaEuropeoDesgloseOperacion_ServioNoSujeto || IvaEuropeoDesgloseOperacion_NoServicioNoSujeto;
953 
954  //Si el tipo de operación es C_FACTUVEN .Operacion = 32, 34 o 35 y C_FACTUVEN.SIIF1NOID =.T.y el cliente NO es Nacional y y tipo_iva de la línea es NO Servicio y No sujeto(tipo_iva.inmovil =.F.y tipo_iva.exento =.T.)
955  var IvaEuropeoDesgloseFactura_NoServicioNoSujeto = (lnOperacion == 32 || lnOperacion == 34 || lnOperacion == 35) && noEsClienteNacional && facturaSinIdentificaciónDelDestinatario && IvaNoServicioNoSujeto;
956 
957  //Si el tipo de operación es C_FACTUVEN .Operacion = 32 o 33 y el cliente es Nacional y tipo_iva de la línea es Servicio Sujeto(tipo_iva.inmovil =.T.y tipo_iva.exento =.F.)
958  var IvaEuropeoDesgloseFactura_ServicioSujeto = (lnOperacion == 32 || lnOperacion == 34) && clienteNacional && IvaServicioSujeto;
959 
960  //Si el tipo de operación es C_FACTUVEN .Operacion = 32 o 34 y el cliente es Nacional y tipo_iva de la línea es NO Servicio Sujeto(tipo_iva.inmovil =.F.y tipo_iva.exento =.F.)
961  var IvaEuropeoDesgloseFactura_NoServicioSujeto = (lnOperacion == 32 || lnOperacion == 34) && clienteNacional && IvaNoServicioSujeto;
962 
963  IvaEuropeoConDesgloseFactura = IvaEuropeoDesgloseFactura_NoServicioNoSujeto ||
964  IvaEuropeoDesgloseFactura_ServicioSujeto ||
965  IvaEuropeoDesgloseFactura_NoServicioSujeto;
966 
967  //Task 185738 => Invalidar Iva Europeo hasta que se soporte por la administración y el componente
968  IvaEuropeoConDesgloseOperacion = false;
969  IvaEuropeoDesgloseOperacion_ServioNoSujeto = false;
970  IvaEuropeoDesgloseOperacion_NoServicioNoSujeto = false;
971  IvaEuropeoConDesgloseFactura = false;
972  IvaEuropeoDesgloseFactura_NoServicioNoSujeto = false;
973  IvaEuropeoDesgloseFactura_ServicioSujeto = false;
974  IvaEuropeoDesgloseFactura_NoServicioSujeto = false;
975 
976 
977  #endregion Evaluar condiciones IVA EUROPEO
978 
979  if (((string.IsNullOrEmpty(nifCli) || !nifCli.StartsWith("N"))
980  && (tipoOpIva == eTipoOperacionEmitidasSII.NacionalNoSujeta ||
981  tipoOpIva == eTipoOperacionEmitidasSII.NacionalSujetaExenta ||
982  tipoOpIva == eTipoOperacionEmitidasSII.NacionalSujetaNoExenta)
983  && !llTratamientoNacinal
984  && !IvaEuropeoConDesgloseOperacion //Se requiere que no sea del tipo que requiere desglose operación
985  )
986  || IvaEuropeoConDesgloseFactura //O sea del tipo que requiere desglose factura
987  || ((idFiscal == 1 || idFiscal == 0 || idFiscal == 7) && extracomunitario) //Task 187715 =>Tipo de documento NIF y Extracomunitario
988  || string.IsNullOrEmpty(nifCli) //Task 187715 => Sin Cif siempre desglose fra.
989  ) //Y no requiere tratamiento iva Europeo por operación
990  {
991  #region Desglose por factura
992 
993  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType == null)
994  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType = new DesgloseFacturaTypeCom();
995  if ((tipoOpIva != eTipoOperacionEmitidasSII.NacionalNoSujeta &&
996  !IvaEuropeoDesgloseFactura_NoServicioNoSujeto) //Y no es Iva Europe No sujeto
997  || IvaEuropeoDesgloseFactura_ServicioSujeto || IvaEuropeoDesgloseFactura_NoServicioSujeto //O es iva Europeo sujeto
998  )//Iva sujeto
999  {
1000  #region Iva sujeto
1001 
1002  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta == null)
1003  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta = new SujetaTypeCom();
1004  if (tipoOpIva == eTipoOperacionEmitidasSII.NacionalSujetaExenta &&
1005  !IvaEuropeoDesgloseFactura_ServicioSujeto && //No es Iva Europeo no exento
1006  !IvaEuropeoDesgloseFactura_NoServicioSujeto //No es Iva Europeo no exento
1007  ) //Iva exento
1008  {
1009  #region Iva exento
1010 
1011  if (facRow["SIIEXENTA"] == null || string.IsNullOrWhiteSpace(facRow["SIIEXENTA"].ToString()))
1012  {
1013  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando desglose IVA por factura exento desde columna IVA");
1014 
1015  var causaExencion = string.Empty;
1016  if (facRow["SIICASUEX"] == null || string.IsNullOrWhiteSpace(facRow["SIICASUEX"].ToString()))
1017  {
1018  //Siempre debería venir lleno pero por si acaso codifico algunos casos especiales
1019  if (lnOperacion.Equals(19))
1020  causaExencion = "E6"; //EntregasNoHabitualesOroInversion
1021  else
1022  causaExencion = "E1"; //Generico
1023  }
1024  else
1025  {
1026  causaExencion = "E" + facRow["SIICASUEX"].ToString().Trim();
1027  }
1028 
1029  var detalle = new DetalleExentaTypeCom
1030  {
1031  CausaExencion = causaExencion,
1032  BaseImponible = CalcularBaseIvaAplicandoEntregas(iva, datosFactura, datosEntregas)
1033  };
1034  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.AddExenta(detalle);
1035  }
1036  else
1037  {
1038  if (!bloqueSIIEXENTAinsertado) //Los datos son por factura, no por tipo de iva => se controla para no duplicar el bloque
1039  {
1040  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando desglose IVA por factura exento desde columna SIIEXENTA");
1041  var causas = GetAllSimpleValuesFromXML(facRow["SIIEXENTA"].ToString(), "causa");
1042  var bases = GetAllSimpleValuesFromXML(facRow["SIIEXENTA"].ToString(), "base");
1043  bases = CalcularBasesExentasAplicandoEntregas(bases, datosFactura, datosEntregas);
1044  for (int i = 0; i < bases.Count; i++)
1045  {
1046  var detalle = new DetalleExentaTypeCom();
1047  if (causas[i] == "7")
1048  detalle.CausaExencion = "E6";
1049  else
1050  detalle.CausaExencion = "E" + causas[i].Trim();
1051  detalle.BaseImponible = bases[i].Trim();
1052  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.AddExenta(detalle);
1053  }
1054  bloqueSIIEXENTAinsertado = true;
1055  }
1056  }
1057 
1058  #endregion Iva exento
1059  }
1060  else //Iva no exento
1061  {
1062  #region Iva no exento
1063 
1064  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando desglose IVA por factura regular desde columna IVA");
1065 
1066  //Task 185108
1067  if (IvaEuropeoDesgloseFactura_ServicioSujeto || IvaEuropeoDesgloseFactura_NoServicioSujeto) //Iva Europeo
1068  {
1069  TipoNoExenta = "S1";
1070  }
1071  else
1072  {
1073  if (ivaPrestacionDeServicios)
1074  {
1075  //Bug 186669 => Tipo S3 no aplica en TBAI
1077  //if (!string.IsNullOrWhiteSpace(TipoNoExenta) && TipoNoExenta != "S2")
1078  //{
1079  // TipoNoExenta = "S3";
1080  //}
1081  //else
1082  //{
1083  // TipoNoExenta = "S2";
1084  //}
1085 
1086  //Operaciones No habituales. Corresponde al enumerado eOperacionesAsientos
1087  //EntregasNoHabitualesOroInversion = 19,
1088  //EntregasOperacionesFinancierasNoHabituales = 36,
1089  //EntregasBienesInmueblesNoHabituales = 37,
1090  if (lnOperacion.Equals(19) || lnOperacion.Equals(36) || lnOperacion.Equals(37))
1091  {
1092  TipoNoExenta = "S1";
1093  }
1094  else
1095  {
1096  TipoNoExenta = "S2";
1097  }
1098  }
1099  else
1100  {
1101  //Bug 186669 => Tipo S3 no aplica en TBAI
1103  //if (!string.IsNullOrWhiteSpace(TipoNoExenta) && TipoNoExenta != "S1")
1104  //{
1105  // TipoNoExenta = "S3";
1106  //}
1107  //else
1108  //{
1109  // TipoNoExenta = "S1";
1110  //}
1111  TipoNoExenta = "S1";
1112  }
1113  }
1114 
1115 
1116  DetalleNoExentaTypeCom detalle;
1117  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta == null ||
1118  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta.Length == 0 ||
1119  (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta.Length == 1 && ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta[0].TipoNoExenta != TipoNoExenta))
1120  {
1121  detalle = new DetalleNoExentaTypeCom
1122  {
1123  TipoNoExenta = TipoNoExenta
1124  };
1125  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.AddNoExenta(detalle);
1126  }
1127  else
1128  {
1129  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta[0].TipoNoExenta == TipoNoExenta)
1130  detalle = ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta[0] as DetalleNoExentaTypeCom;
1131  else
1132  detalle = ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta[1] as DetalleNoExentaTypeCom;
1133  }
1134 
1135  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Leidas bases de IVA. Rellenando DesgloseIVA componente");
1136 
1137  //Task 200300
1138  var detalleIva = GenerarDetalleIvaTypoCom(iva, datosFactura, datosEntregas);
1139  detalle.AddDesgloseIVA(detalleIva);
1140 
1141  #endregion Iva no exento
1142  }
1143 
1144  #endregion Iva sujeto
1145  }
1146  else //Iva no sujeto
1147  {
1148  #region Iva no sujeto
1149 
1150  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando desglose IVA por factura no sujeto desde columna IVA");
1151 
1152  var detalle = new DetalleNoSujetaCom();
1153 
1154  if (IvaEuropeoDesgloseFactura_NoServicioNoSujeto)
1155  {
1156  detalle.Causa = "RL";
1157  detalle.Importe = CalcularBaseIvaAplicandoEntregas(iva, datosFactura, datosEntregas);
1158  }
1159  else
1160  {
1161  detalle.Causa = (Convert.ToInt16(facRow["SIICANOSU"]) - 1).ToString().Trim();
1162  detalle.Importe = CalcularBaseIvaAplicandoEntregas(iva, datosFactura, datosEntregas);
1163  }
1164  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.AddNoSujeta(detalle);
1165 
1166  #endregion Iva no sujeto
1167  }
1168 
1169  #endregion Desglose por factura
1170  }
1171  else //OPCION 2.Desglose por tipo operación
1172  {
1173  #region Desglose por tipo operación
1174 
1175  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType == null)
1176  {
1177  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType = new DesgloseTipoOperacionTypeCom();
1178  }
1179 
1180  if (((tipoOpIva == eTipoOperacionEmitidasSII.ExtracomunitariaNoSujeta && !NifClienteEsEspecialOperaciones(nifCli)) || //Bug 185586 => Que no entre con Nifs especiales
1181  iva._IvaServicios ||
1182  ivaPrestacionDeServicios ||
1183  IvaEuropeoDesgloseOperacion_ServioNoSujeto)
1184  && !IvaEuropeoDesgloseOperacion_NoServicioNoSujeto)
1185  {
1186  #region Iva de prestacion de servicios
1187 
1188  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios == null)
1189  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios = new PrestacionServiciosCom();
1190 
1191  if (tipoOpIva != eTipoOperacionEmitidasSII.NacionalNoSujeta &&
1192  llTratamientoNacinal &&
1193  !IvaEuropeoDesgloseOperacion_ServioNoSujeto //Si cumple esto que salte al bloque no sujeto
1194  ) //Iva sujeto // Segun el mapeo no existen de esta tipologia
1195  {
1196  #region Iva sujeto
1197 
1198  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta == null)
1199  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta = new SujetaTypeCom();
1200  if (tipoOpIva == eTipoOperacionEmitidasSII.NacionalSujetaExenta) //Iva exento
1201  {
1202  #region Iva exento
1203 
1204  if (facRow["SIIEXENTA"] == null || string.IsNullOrWhiteSpace(facRow["SIIEXENTA"].ToString()))
1205  {
1206  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando desglose IVA por factura exento desde columna IVA");
1207 
1208  var causaExencion = string.Empty;
1209  if (facRow["SIICASUEX"] == null || string.IsNullOrWhiteSpace(facRow["SIICASUEX"].ToString()))
1210  {
1211  //Siempre debería venir lleno pero por si acaso codifico algunos casos especiales
1212  if (lnOperacion.Equals(19))
1213  causaExencion = "E6"; //EntregasNoHabitualesOroInversion
1214  else
1215  causaExencion = "E1"; //Generico
1216  }
1217  else
1218  {
1219  causaExencion = "E" + facRow["SIICASUEX"].ToString().Trim();
1220  }
1221 
1222  var detalle = new DetalleExentaTypeCom
1223  {
1224  CausaExencion = causaExencion,
1225  BaseImponible = CalcularBaseIvaAplicandoEntregas(iva,datosFactura,datosEntregas)
1226  };
1227 
1228  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.AddExenta(detalle);
1229  }
1230  else
1231  {
1232  if (!bloqueSIIEXENTAinsertado) //Los datos son por factura, no por tipo de iva => se controla para no duplicar el bloque
1233  {
1234  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando desglose IVA por factura exento desde columna SIIEXENTA");
1235  var causas = GetAllSimpleValuesFromXML(facRow["SIIEXENTA"].ToString(), "causa");
1236  var bases = GetAllSimpleValuesFromXML(facRow["SIIEXENTA"].ToString(), "base");
1237  bases = CalcularBasesExentasAplicandoEntregas(bases, datosFactura, datosEntregas);
1238  for (int i = 0; i < bases.Count; i++)
1239  {
1240  var detalle = new DetalleExentaTypeCom();
1241  if (causas[i] == "7")
1242  detalle.CausaExencion = "E6";
1243  else
1244  detalle.CausaExencion = "E" + causas[i].Trim();
1245  detalle.BaseImponible = bases[i].Trim();
1246  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.AddExenta(detalle);
1247  }
1248  bloqueSIIEXENTAinsertado = true;
1249  }
1250  }
1251 
1252  #endregion Iva exento
1253  }
1254  else //Iva no exento
1255  {
1256  #region Iva no exento
1257 
1258  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando desglose IVA por factura regular desde columna IVA");
1259 
1260  //Task 185108
1261  if (ivaPrestacionDeServicios)
1262  {
1263  //Bug 186669 => Tipo S3 no aplica en TBAI
1265  //if (!string.IsNullOrWhiteSpace(TipoNoExenta) && TipoNoExenta != "S2")
1266  //{
1267  // TipoNoExenta = "S3";
1268  //}
1269  //else
1270  //{
1271  // TipoNoExenta = "S2";
1272  //}
1273 
1274  //Operaciones No habituales. Corresponde al enumerado eOperacionesAsientos
1275  //EntregasNoHabitualesOroInversion = 19,
1276  //EntregasOperacionesFinancierasNoHabituales = 36,
1277  //EntregasBienesInmueblesNoHabituales = 37,
1278  if (lnOperacion.Equals(19) || lnOperacion.Equals(36) || lnOperacion.Equals(37))
1279  {
1280  TipoNoExenta = "S1";
1281  }
1282  else
1283  {
1284  TipoNoExenta = "S2";
1285  }
1286  }
1287  else
1288  {
1289  //Bug 186669 => Tipo S3 no aplica en TBAI
1291  //if (!string.IsNullOrWhiteSpace(TipoNoExenta) && TipoNoExenta != "S1")
1292  //{
1293  // if (iva._IvaServicios) TipoNoExenta = "S1";
1294  // else TipoNoExenta = "S3";
1295  //}
1296  //else
1297  //{
1298  // TipoNoExenta = "S1";
1299  //}
1300  TipoNoExenta = "S1";
1301  }
1302 
1303  DetalleNoExentaTypeCom detalle;
1304  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta == null ||
1305  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta.Length == 0 ||
1306  (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta.Length == 1 &&
1307  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta[0].TipoNoExenta != TipoNoExenta))
1308  {
1309  detalle = new DetalleNoExentaTypeCom
1310  {
1311  TipoNoExenta = TipoNoExenta
1312  };
1313  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.AddNoExenta(detalle);
1314  }
1315  else
1316  {
1317  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta[0].TipoNoExenta == TipoNoExenta)
1318  detalle = ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta[0] as DetalleNoExentaTypeCom;
1319  else
1320  detalle = ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta[1] as DetalleNoExentaTypeCom;
1321  }
1322 
1323  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Leidas bases de IVA. Rellenando DesgloseIVA componente");
1324 
1325  //Task 200300
1326  var detalleIva = GenerarDetalleIvaTypoCom(iva, datosFactura, datosEntregas);
1327  detalle.AddDesgloseIVA(detalleIva);
1328 
1329  #endregion Iva no exento
1330  }
1331 
1332  #endregion Iva sujeto
1333 
1334  }
1335  else //Iva no sujeto
1336  {
1337  #region Iva no sujeto
1338 
1339  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando desglose IVA por operacion de servicios no sujeto desde columna IVA");
1340 
1341  var detalle = new DetalleNoSujetaCom();
1342 
1343  if (IvaEuropeoDesgloseOperacion_ServioNoSujeto) //Específico Iva Europeo
1344  {
1345  detalle.Causa = "RL";
1346  detalle.Importe = CalcularBaseIvaAplicandoEntregas(iva, datosFactura, datosEntregas); //Santi => Debería ser acumulado
1347  }
1348  else //Caso normal
1349  {
1350  detalle.Causa = (Convert.ToInt16(facRow["SIICANOSU"]) - 1).ToString().Trim();
1351  detalle.Importe = CalcularBaseIvaAplicandoEntregas(iva, datosFactura, datosEntregas);
1352  }
1353 
1354 
1355  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.AddNoSujeta(detalle);
1356 
1357  #endregion Iva no sujeto
1358  }
1359 
1360  #endregion Iva de prestacion de servicios
1361  }
1362  else //Iva de entrega de bienes
1363  {
1364  #region Iva de entrega de bienes
1365 
1366  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega == null)
1367  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega = new EntregaCom();
1368  if ((tipoOpIva == eTipoOperacionEmitidasSII.NacionalSujetaExenta ||
1369  tipoOpIva == eTipoOperacionEmitidasSII.ComunitariaSujetaExenta ||
1370  tipoOpIva == eTipoOperacionEmitidasSII.ExtracomunitariaSujetaExenta ||
1371  tipoOpIva == eTipoOperacionEmitidasSII.NacionalSujetaNoExenta) //Iva sujeto
1372  && !IvaEuropeoDesgloseOperacion_NoServicioNoSujeto)
1373  {
1374  #region Iva sujeto
1375 
1376  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta == null)
1377  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta = new SujetaTypeCom();
1378 
1379  if (tipoOpIva != eTipoOperacionEmitidasSII.NacionalSujetaNoExenta && (comunitario || extracomunitario || NifClienteEsEspecialOperaciones(nifCli))) //Iva exento
1380  {
1381  #region Iva exento
1382 
1383  if (facRow["SIIEXENTA"] == null || string.IsNullOrWhiteSpace(facRow["SIIEXENTA"].ToString()))
1384  {
1385  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando desglose IVA por operacion de bienes exento desde columna IVA");
1386  var causaExencion = string.Empty;
1387  if (facRow["SIICASUEX"] == null || string.IsNullOrWhiteSpace(facRow["SIICASUEX"].ToString()))
1388  {
1389  //Siempre debería venir lleno pero por si acaso codifico algunos casos especiales
1390  if (lnOperacion.Equals(19))
1391  causaExencion = "E6"; //EntregasNoHabitualesOroInversion
1392  else
1393  causaExencion = "E1"; //Generico
1394  }
1395  else
1396  {
1397  causaExencion = "E" + facRow["SIICASUEX"].ToString().Trim();
1398  }
1399 
1400  var detalle = new DetalleExentaTypeCom
1401  {
1402  CausaExencion = causaExencion,
1403  BaseImponible = CalcularBaseIvaAplicandoEntregas(iva, datosFactura, datosEntregas)
1404  };
1405  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.AddExenta(detalle);
1406  }
1407  else
1408  {
1409  if (!bloqueSIIEXENTAinsertado) //Los datos son por factura, no por tipo de iva => se controla para no duplicar el bloque
1410  {
1411  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando desglose IVA por operacion de bienes exento desde columna SIIEXENTA");
1412  var causas = GetAllSimpleValuesFromXML(facRow["SIIEXENTA"].ToString(), "causa");
1413  var bases = GetAllSimpleValuesFromXML(facRow["SIIEXENTA"].ToString(), "base");
1414  bases = CalcularBasesExentasAplicandoEntregas(bases, datosFactura, datosEntregas);
1415  for (int i = 0; i < bases.Count; i++)
1416  {
1417  var detalle = new DetalleExentaTypeCom();
1418  if (causas[i] == "7")
1419  detalle.CausaExencion = "E6";
1420  else
1421  detalle.CausaExencion = "E" + causas[i].Trim();
1422  detalle.BaseImponible = bases[i].Trim();
1423  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.AddExenta(detalle);
1424  }
1425  bloqueSIIEXENTAinsertado = true;
1426  }
1427  }
1428 
1429  #endregion Iva exento
1430  }
1431  else //Iva no exento //Segun el mapeo esta tipologia no existe
1432  {
1433  #region Iva no exento
1434 
1435  //Nada porque no existe esta tipologia segun Mapeo
1436 
1437  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando desglose IVA por tipo operación, Iva de entrega de bienes no exento");
1438 
1439  //Task 185108
1440  if (ivaPrestacionDeServicios)
1441  {
1442  //Bug 186669 => Tipo S3 no aplica en TBAI
1444  //if (!string.IsNullOrWhiteSpace(TipoNoExenta) && TipoNoExenta != "S2")
1445  //{
1446  // TipoNoExenta = "S3";
1447  //}
1448  //else
1449  //{
1450  // TipoNoExenta = "S2";
1451  //}
1452 
1453  //Operaciones No habituales. Corresponde al enumerado eOperacionesAsientos
1454  //EntregasNoHabitualesOroInversion = 19,
1455  //EntregasOperacionesFinancierasNoHabituales = 36,
1456  //EntregasBienesInmueblesNoHabituales = 37,
1457  if (lnOperacion.Equals(19) || lnOperacion.Equals(36) || lnOperacion.Equals(37))
1458  {
1459  TipoNoExenta = "S1";
1460  }
1461  else
1462  {
1463  TipoNoExenta = "S2";
1464  }
1465  }
1466  else
1467  {
1468  //Bug 186669 => Tipo S3 no aplica en TBAI
1470  //if (!string.IsNullOrWhiteSpace(TipoNoExenta) && TipoNoExenta != "S1")
1471  //{
1472  // if (iva._IvaServicios) TipoNoExenta = "S1";
1473  // else TipoNoExenta = "S3";
1474  //}
1475  //else
1476  //{
1477  // TipoNoExenta = "S1";
1478  //}
1479  TipoNoExenta = "S1";
1480  }
1481 
1482 
1483  DetalleNoExentaTypeCom detalle;
1484  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta == null ||
1485  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta.Length == 0 ||
1486  (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta.Length == 1 &&
1487  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta[0].TipoNoExenta != TipoNoExenta))
1488  {
1489  detalle = new DetalleNoExentaTypeCom
1490  {
1491  TipoNoExenta = TipoNoExenta
1492  };
1493  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.AddNoExenta(detalle);
1494  }
1495  else
1496  {
1497  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta[0].TipoNoExenta == TipoNoExenta)
1498  detalle = ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta[0] as DetalleNoExentaTypeCom;
1499  else
1500  detalle = ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta[1] as DetalleNoExentaTypeCom;
1501  }
1502 
1503  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Leidas bases de IVA. Rellenando DesgloseIVA componente");
1504 
1505  //Task 200300
1506  var detalleIva = GenerarDetalleIvaTypoCom(iva, datosFactura, datosEntregas);
1507  detalle.AddDesgloseIVA(detalleIva);
1508 
1509  #endregion Iva no exento
1510  }
1511 
1512  #endregion Iva no sujeto
1513  }
1514  else //Iva no sujeto
1515  {
1516  #region Iva no sujeto
1517 
1518  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Rellenando desglose IVA por operacion de bienes no sujeto desde columna IVA");
1519  var detalle = new DetalleNoSujetaCom();
1520 
1521  if (IvaEuropeoDesgloseOperacion_NoServicioNoSujeto)
1522  {
1523  detalle.Causa = "RL";
1524  detalle.Importe = CalcularBaseIvaAplicandoEntregas(iva, datosFactura, datosEntregas); //Santi => Sumatorio?
1525  }
1526  else
1527  {
1528  detalle.Causa = (Convert.ToInt16(facRow["SIICANOSU"]) - 1).ToString().Trim();
1529  detalle.Importe = CalcularBaseIvaAplicandoEntregas(iva, datosFactura, datosEntregas);
1530  }
1531  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.AddNoSujeta(detalle);
1532 
1533  #endregion Iva no sujeto
1534  }
1535 
1536  #endregion Iva de entrega de bienes
1537  }
1538 
1539  #endregion Desglose por tipo operación
1540  }
1541  }
1542 
1543  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Finalizado desglose IVA. Rellenando Huella TBAI");
1544 
1545  // HuellaTBAI
1546  ticketBaiCom.HuellaTBAI = new Sage.ES.TicketBAI.Entities.ComModel.Invoice.V1_0.HuellaTBAICom();
1547 
1548  //if (!string.IsNullOrWhiteSpace(XML_generator_parameters.SerieDocumentoAnterior) && //Bug 185139 => con Fra. expedicion manual o DER puede no tener serie
1549  if (!string.IsNullOrWhiteSpace(XML_generator_parameters.NumDocumentoAnterior) &&
1550  XML_generator_parameters.FechaDocumentoAnterior.HasValue &&
1551  !string.IsNullOrWhiteSpace(XML_generator_parameters.FirmaDocumentoAnterior))
1552  {
1553  // Encadenamiento factura anterior
1554  ticketBaiCom.HuellaTBAI.EncadenamientoFacturaAnterior = new EncadenamientoFacturaAnteriorTypeCom()
1555  {
1556  SerieFacturaAnterior = string.IsNullOrWhiteSpace(XML_generator_parameters.SerieDocumentoAnterior) ? "" : XML_generator_parameters.SerieDocumentoAnterior.Trim(),
1557  NumFacturaAnterior = string.IsNullOrWhiteSpace(XML_generator_parameters.NumDocumentoAnterior) ? "" : XML_generator_parameters.NumDocumentoAnterior.Trim(),
1558  FechaExpedicionFacturaAnterior = (XML_generator_parameters.FechaDocumentoAnterior.HasValue) ? XML_generator_parameters.FechaDocumentoAnterior.Value.ToString("dd-MM-yyyy") : "",
1559  SignatureValueFirmaFacturaAnterior = XML_generator_parameters.FirmaDocumentoAnterior.Trim()
1560  };
1561  }
1562 
1563  // Software facturacion
1564  ticketBaiCom.HuellaTBAI.Software = Generar_SoftwareFacturacionTypeCom();
1565 
1566  ticketBaiCom.HuellaTBAI.NumSerieDispositivo = TerminalSerialNumber.Trim();
1567  }
1568 
1569  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Creando la instancia del process del componente");
1570  // Generates the xml file, signs and converts to base64 message.
1571  var processObj = _process as object;
1572  var procesoCreado = CreateProcess(outputFilename, ticketBaiCom.Sujetos.Emisor.Territorio, false, false, ref processObj, Convert.ToDateTime(ticketBaiCom.Factura.CabeceraFactura.FechaExpedicionFactura));
1573  if (_process != null)
1574  {
1575  _process.TicketBaiCom_V1_0 = ticketBaiCom;
1576  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Generando el XML desde el componente");
1577  if (_process.GenerateCom())
1578  {
1579  ErrorMessage = "";
1580  GeneratedSignature = _process.SignatureString;
1581  GeneratedTBaiCode = _process.GetStringTBAI;
1582  GeneratedTBaiQR = _process.GetStringQR;
1583  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Todo correcto, devolviendo datos.");
1584  //180350
1585  FacturasCreadasEstaSesionSinEnviar.Add(datosFactura._Factura.Trim());
1586  return true;
1587  }
1588  else
1589  {
1590  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Componente devuelve error: " + _process.MsgError);
1591  ErrorMessage = "Proceso de generación terminado con incidencias. Consulta el fichero de Log para ver los detalles." + Environment.NewLine +
1592  Environment.NewLine + "Error: " + _process.MsgError.Trim();
1593  }
1594  }
1595  }
1596  catch (Exception ex)
1597  {
1598  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataInternal: Excepción durante la generación." + ex.Message);
1599  DB.Registrar_Error(ex);
1600  ErrorMessage = "Error durante el proceso de generación. Mensaje: " + ex.Message;
1601  }
1602  finally
1603  {
1604  if (ticketBaiCom != null)
1605  {
1606  ticketBaiCom.Dispose();
1607  ticketBaiCom = null;
1608  }
1609  }
1610 
1611  return false;
1612  }
1613 
1621  private bool GenerateTicketBaiDataTicketsInternal(string outputFilename, ewDocVentaTPV datosTicket, TicketBai_XML_Parameters XML_generator_parameters)
1622  {
1623  // Objects of COM model.
1624  TicketBaiCom ticketBaiCom = null;
1625  GeneratedSignature = "";
1626 
1627  GenerateTrace("ExportadorFactuCertXML: Entrando en GenerateTicketBaiDataTicketsInternal");
1628 
1629  try
1630  {
1631  // TicketBai
1632  ticketBaiCom = new TicketBaiCom();
1633 
1634  {
1635  // Cabecera
1636  ticketBaiCom.Cabecera = new CabeceraCom()
1637  {
1638  IDVersionTBAI = "1.2"
1639  };
1640 
1641  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando sujeto");
1642  // Sujetos
1643  ticketBaiCom.Sujetos = new SujetosCom()
1644  {
1645  // Emisor
1646  Emisor = new EmisorCom()
1647  {
1648  NIF = NormalizarCaracteresNif(((ew.empresa.Empresa)EW_GLOBAL._Empresa)._CifTC),
1649  ApellidosNombreRazonSocial = ((ew.empresa.Empresa)EW_GLOBAL._Empresa)._ApellidosTC + " " + ((ew.empresa.Empresa)EW_GLOBAL._Empresa)._NombreTC.Trim(),
1650  },
1651  VariosDestinatarios = "N",
1652  VariosDestinatariosSpecified = true,
1653  EmitidaPorTercerosODestinatario = "N",
1654  EmitidaPorTercerosODestinatarioSpecified = true
1655  };
1656 
1657  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Obteniendo datos de CONTADO");
1658  //Obtenemos los datos que necesitamos de contado para rellenar el XML
1659  DataRow contadoRow = GetRowCompletoTabla("GESTION", "CONTADO", "EMPRESA = '" + EW_GLOBAL._GetVariable("wc_empresa").ToString() + "' AND LETRA = '" + datosTicket._Letra + "' AND NUMERO = '" + datosTicket._Numero + "'");
1660 
1661  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Generando destinatario");
1662  // Destinatarios
1663  var destinatario = new IDDestinatarioCom
1664  {
1665  ApellidosNombreRazonSocial = contadoRow != null && contadoRow["nombre"] != null && !string.IsNullOrWhiteSpace(contadoRow["nombre"].ToString()) ? contadoRow["nombre"].ToString().Trim() : "",
1666  CodigoPostal = contadoRow != null && contadoRow["codpost"] != null && !string.IsNullOrWhiteSpace(contadoRow["codpost"].ToString()) ? contadoRow["codpost"].ToString().Trim() : "",
1667  Direccion = contadoRow != null && contadoRow["direccion"] != null && !string.IsNullOrWhiteSpace(contadoRow["direccion"].ToString()) ? contadoRow["direccion"].ToString().Trim() : "",
1668  Item_NIF = contadoRow != null && contadoRow["CIF"] != null && !string.IsNullOrWhiteSpace(contadoRow["CIF"].ToString()) ? NormalizarCaracteresNif(contadoRow["CIF"].ToString()) : ""
1669  };
1670 
1671  //Quitar warning
1672  //if (true) //171904 - finalmente nunca informar destinatario en tickets. ¯\_(ツ)_/¯ //string.IsNullOrWhiteSpace(destinatario.ApellidosNombreRazonSocial) || string.IsNullOrWhiteSpace(destinatario.Item_NIF))
1673  //{
1674  // //Nada
1675  //}
1676  //else
1677  //{
1678  // ticketBaiCom.Sujetos.Destinatarios = new IDDestinatarioCom[] { destinatario };
1679  //}
1680 
1681  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Obtenemos datos de tabla FCTICKETS", "Params: " + EW_GLOBAL._GetVariable("wc_empresa").ToString() + " / " + EW_GLOBAL._GetVariable("wc_any").ToString().Trim() + " / " + datosTicket._Letra + " / " + datosTicket._Numero);
1682  DataRow fcTicketRow = GetRowCompletoTabla(FACTUCERT._NombreAddOn, "FCTICKETS", "EMPRESA = '" + EW_GLOBAL._GetVariable("wc_empresa").ToString() + "' AND EJERCICIO = '" + EW_GLOBAL._GetVariable("wc_any").ToString().Trim() + "' AND LETRA = '" + datosTicket._Letra + "' AND NUMERO = '" + datosTicket._Numero + "'");
1683 
1684  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Resultado consulta FCTICKETS -> " + (fcTicketRow != null).ToString());
1685 
1686  if (fcTicketRow == null)
1687  throw new Exception("No ha podido leerse correctamente la información de Factura Certificada del ticket " + datosTicket._Letra + " / " + datosTicket._Numero);
1688 
1689  //Nuevo v1.0.1 componente
1690  switch (fcTicketRow["territorio"].ToString())
1691  {
1692  case "1":
1693  ticketBaiCom.Sujetos.Emisor.Territorio = "2";
1694  break;
1695  case "2":
1696  ticketBaiCom.Sujetos.Emisor.Territorio = "4";
1697  break;
1698  case "3":
1699  ticketBaiCom.Sujetos.Emisor.Territorio = "3";
1700  break;
1701  default:
1702  ErrorMessage = "El Ticket seleccionado para el envío no tiene correctamente especificado el Territorio de expedición. No es posible continuar con el envío.";
1703  return false;
1704  }
1705  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenado el territorio " + ticketBaiCom.Sujetos.Emisor.Territorio.ToString());
1706 
1707  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Generando la cabecera de la Factura");
1708  // Factura
1709  ticketBaiCom.Factura = new FacturaCom()
1710  {
1711  // Cabecera factura
1712  CabeceraFactura = new ComModel.Invoice.V1_0.CabeceraFacturaTypeCom()
1713  {
1714  SerieFactura = datosTicket._Letra.Trim(),
1715  NumFactura = datosTicket._Numero.Trim(),
1716  FechaExpedicionFactura = datosTicket._Fecha.ToString("dd-MM-yyyy"),
1717  HoraExpedicionFactura = XML_generator_parameters.HoraCertificacion?.Trim(),
1718  FacturaSimplificada = "S",
1719  FacturaSimplificadaSpecified = true,
1720  FacturaEmitidaSustitucionSimplificada = "N",
1721  FacturaEmitidaSustitucionSimplificadaSpecified = true
1722  }
1723  };
1724 
1725  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Viendo si es rectificativa a partir de SIIORIMOT");
1726  // Factura rectificativa
1727  if (fcTicketRow["TBORITIP"] != null && fcTicketRow["TBORITIP"] != DBNull.Value && !string.IsNullOrWhiteSpace(fcTicketRow["TBORITIP"].ToString()))
1728  {
1729  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Es rectificativa, rellenamos datos");
1730  ticketBaiCom.Factura.CabeceraFactura.FacturaRectificativa = new FacturaRectificativaTypeCom()
1731  {
1732  Codigo = "R5",
1733  Tipo = fcTicketRow["TBORITIP"]?.ToString().Trim(),
1734  };
1735 
1736  //2 Caminos => Simple y múltiple. Para múltiple (TBORITIP=S y TBORICAN=2) hay que usar el campo D_TICKERECT.TICKET_RECT y D_TICKERECT.FECHA
1737  if (Convert.ToString(fcTicketRow["TBORITIP"]) == "S" && Convert.ToString(fcTicketRow["TBORICAN"]) == "2")
1738  {
1739  //Rectificativa múltiple
1740  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Datos facturas sustituidas a partir de D_TICKERECT");
1741 
1742  //Recuperar los datos
1743  List<IDFacturaRectificadaSustituidaTypeCom> lstSustituidas = new List<IDFacturaRectificadaSustituidaTypeCom>();
1744 
1745  decimal baseRectificada = decimal.Zero; //Campos para acumular
1746  decimal cuotaRectificada = decimal.Zero;
1747  decimal cuotaRecargoRectificada = decimal.Zero;
1748  foreach (DetalleTicketRectificativoDTO ticketRectificado in ObtenerDatosRectificadasMultiplesTickets(datosTicket._Numero, datosTicket._Letra))
1749  {
1750  //Actualizo el importe acumulado de la rectificación
1751  baseRectificada += ticketRectificado.Base_iva;
1752  cuotaRectificada += ticketRectificado.Iva;
1753  cuotaRecargoRectificada += ticketRectificado.Recargo;
1754 
1755  var fraSustituida = new IDFacturaRectificadaSustituidaTypeCom
1756  {
1757  SerieFactura = ticketRectificado.Letra_rect,
1758  NumFactura = ticketRectificado.Ticket_rect,
1759  FechaExpedicionFactura = ticketRectificado.Fecha.ToString("dd-MM-yyyy")
1760  };
1761  lstSustituidas.Add(fraSustituida);
1762  }
1763 
1764  ticketBaiCom.Factura.CabeceraFactura.FacturaRectificativa.ImporteRectificacionSustitutiva = new ImporteRectificacionSustitutivaTypeCom()
1765  {
1766  BaseRectificada = baseRectificada.ToString(_mascaraParaTicketBAI).Trim(),
1767  CuotaRectificada = cuotaRectificada.ToString(_mascaraParaTicketBAI).Trim(),
1768  CuotaRecargoRectificada = cuotaRecargoRectificada.ToString(_mascaraParaTicketBAI).Trim(),
1769  };
1770 
1771  ticketBaiCom.Factura.CabeceraFactura.FacturasRectificadasSustituidas = lstSustituidas.ToArray();
1772  }
1773  else //Rectificativa normal
1774  {
1775 
1776  // Importe factura rectificativa
1777  //177950
1778  if (Convert.ToString(fcTicketRow["TBORITIP"]) == "S")
1779  {
1780  ticketBaiCom.Factura.CabeceraFactura.FacturaRectificativa.ImporteRectificacionSustitutiva = new ImporteRectificacionSustitutivaTypeCom()
1781  {
1782  BaseRectificada = Convert.ToString(fcTicketRow["TBORITIP"]) == "S" ? Convert.ToDecimal(fcTicketRow["TBORIBAS"]).ToString(_mascaraParaCertificacion).Trim() : "",
1783  CuotaRectificada = Convert.ToString(fcTicketRow["TBORITIP"]) == "S" ? Convert.ToDecimal(fcTicketRow["TBORIIVA"]).ToString(_mascaraParaCertificacion).Trim() : "",
1784  CuotaRecargoRectificada = Convert.ToString(fcTicketRow["TBORITIP"]) == "S" ? Convert.ToDecimal(fcTicketRow["TBORIREC"]).ToString(_mascaraParaCertificacion).Trim() : "",
1785  };
1786  }
1787 
1788  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Datos facturas sustituidas a partir de TBORIFRA");
1789  // Identificadores facturas rectificadas sustituidas.
1790  if (fcTicketRow["TBORIFRA"] != null && fcTicketRow["TBORIFRA"] != DBNull.Value && !string.IsNullOrWhiteSpace(fcTicketRow["TBORIFRA"].ToString()))
1791  {
1792  ticketBaiCom.Factura.CabeceraFactura.FacturasRectificadasSustituidas = new IDFacturaRectificadaSustituidaTypeCom[]
1793  {
1794  new IDFacturaRectificadaSustituidaTypeCom
1795  {
1796  SerieFactura = (fcTicketRow["TBORIFRA"] != null && fcTicketRow["TBORIFRA"] != DBNull.Value && !string.IsNullOrWhiteSpace(fcTicketRow["TBORIFRA"].ToString())) ? fcTicketRow["TBORIFRA"].ToString().Substring(0, 2).Trim() : "",
1797  NumFactura = (fcTicketRow["TBORIFRA"] != null && fcTicketRow["TBORIFRA"] != DBNull.Value && !string.IsNullOrWhiteSpace(fcTicketRow["TBORIFRA"].ToString())) ? fcTicketRow["TBORIFRA"].ToString().Substring(2).Trim() : "",
1798  FechaExpedicionFactura = (fcTicketRow["TBORIFEC"] != null && fcTicketRow["TBORIFEC"] != DBNull.Value) ? ((DateTime)fcTicketRow["TBORIFEC"]).ToString("dd-MM-yyyy") : "",
1799  },
1800  };
1801  }
1802  }
1803  }
1804 
1805  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Generando el cuerpo de la Factura");
1806  // Datos factura
1807  ticketBaiCom.Factura.DatosFactura = new DatosFacturaTypeCom()
1808  {
1809  DescripcionFactura = "N/FRA " + datosTicket._Letra.Trim() + datosTicket._Numero.Trim() + " " + destinatario.ApellidosNombreRazonSocial.Trim(),
1810 
1811  ImporteTotalFactura = GetImporteTotalFacturaTickets(datosTicket).ToString(_mascaraParaCertificacion),
1812  };
1813 
1814  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Generando las líneas a partir de los Albaranes");
1815  //Detalles de albaranes
1816 
1817  //CCR 199730
1818  var hayPuntoVerde = Convert.ToBoolean(EW_GLOBAL._GetVariable("wl_pverde")) && !datosTicket._Cabecera._oCliente._NoApli_Impuesto_Artic;
1819 
1820 #if SuplidosDtosPortes
1821  //Task 185731 => Suprimir líneas de suplidos
1822  var lineasTicket = datosTicket._Lineas.Where(l => l._Suplido.Equals(false)).ToList(); //Eliminar suplidos
1823  foreach (var linea in lineasTicket)
1824 #else
1825  foreach (var linea in datosTicket._Lineas)
1826 #endif
1827  {
1828  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Procesando línea albarán " + linea._Numero + "-" + linea._Linea);
1829  //if (linea._Unidades != 0 && linea._Precio != 0)
1830  if (!string.IsNullOrWhiteSpace(linea._TipoIva))
1831  {
1832  var lineaAlb = new IDDetalleFacturaTypeCom
1833  {
1834  DescripcionDetalle = linea._Definicion.Trim(),
1835  ImporteUnitario = linea._Precio.ToString(_mascara8decimales),
1836  ImporteTotal = linea._ImporteIva.ToString(GetMascaraEspecificaPorTerritorio("ImporteTotal", _mascaraParaCertificacion)),
1837  };
1838 
1839  //104842/172899
1840  /*
1841  1.- SI D_ALBVEN.TIPOPREC =0 o D_ALBVEN.TIPOPREC=2 ENTONCES:
1842  ---- - Si D_ALBVEN.PESO <> 0 INFORMAR DICHO VALOR DEL CAMPO D_ALBVEN.PESO
1843  ---- - Si D_ALBVEN.PESO = 0 INFORMAR EL VALOR DEL CAMPO D_ALBVEN.UNIDADES
1844  2.- SI D_ALBVEN.TIPOPREC = 1 ENTONCES INFORMAR EL VALOR DEL CAMPO D_ALBVEN.CAJAS
1845  3.- SI D_ALBVEN.TIPOPREC = 3 ENTONCES:
1846  ---- - Si D_ALBVEN.PESO <> 0 INFORMAR DICHO VALOR DEL CAMPO D_ALBVEN.PESO / 1000
1847  ---- - Si D_ALBVEN.PESO = 0 INFORMAR EL VALOR DEL CAMPO D_ALBVEN.UNIDADES / 1000
1848  */
1849  decimal cantidad;
1850  switch (linea._TipoPrec)
1851  {
1852  case 0:
1853  case 2:
1854  if (linea._Peso != 0)
1855  cantidad = linea._Peso;
1856  else
1857  cantidad = linea._Unidades;
1858  break;
1859  case 1:
1860  cantidad = linea._Cajas;
1861  break;
1862  case 3:
1863  if (linea._Peso != 0)
1864  cantidad = linea._Peso / 1000m;
1865  else
1866  cantidad = linea._Unidades / 1000m;
1867  break;
1868  default:
1869  //Por aqui no deberia entrar
1870  throw new NotSupportedException("El tipo de precio de la línea no está soportado");
1871  }
1872  lineaAlb.Cantidad = cantidad.ToString(GetMascaraEspecificaPorTerritorio("Cantidad", _mascaraParaCertificacion));
1873  lineaAlb.Descuento = ((cantidad * linea._Precio) - linea._Importe).ToString(GetMascaraEspecificaPorTerritorio("Descuento", _mascaraParaCertificacion));
1874 
1875  ticketBaiCom.Factura.DatosFactura.AddDetalleFactura(lineaAlb);
1876 
1877  if (hayPuntoVerde && !linea._PuntoVerde.Equals(decimal.Zero) && !cantidad.Equals(decimal.Zero))
1878  {
1879  var literalPVerde = ((ew.empresa.Empresa)EW_GLOBAL._Empresa)._TituloImpuestoArticulo.TrimEnd();
1880 
1881  var lineaPVerde = new IDDetalleFacturaTypeCom
1882  {
1883  DescripcionDetalle = literalPVerde,
1884  Cantidad = (1).ToString(_mascara8decimales),
1885  ImporteUnitario = linea._PuntoVerde.ToString(_mascara8decimales),
1886  };
1887 
1888  sage.ew.articulo.TipoIVA tipoIva = new sage.ew.articulo.TipoIVA()
1889  {
1890  _Codigo = linea._TipoIva
1891  };
1892  decimal porcentajeIva = tipoIva._IVA;
1893  //decimal porcentajeIva = datosFactura._TipoIvaLineas.Where(TI => TI._Codigo == linea._TipoIva).Select(TI => TI._PrcIva).FirstOrDefault();
1894  decimal importeDelPuntoVerde = (linea._PuntoVerde * (1 + (porcentajeIva / 100m))); //Añado el IVA
1895 
1896  if (datosTicket._Cabecera._oCliente._Recargo)
1897  {
1898  //decimal porcentajeRecargo = datosFactura._TipoIvaLineas.Where(TI => TI._Codigo == linea._TipoIva).Select(TI => TI._PrcRecEquiv).FirstOrDefault();
1899  decimal porcentajeRecargo = tipoIva._Recargo;
1900  importeDelPuntoVerde += (linea._PuntoVerde * porcentajeRecargo / 100m); //Añado el recargo
1901  }
1902 
1903  lineaPVerde.ImporteTotal = (importeDelPuntoVerde).ToString(GetMascaraEspecificaPorTerritorio("ImporteTotal", _mascaraParaCertificacion));
1904 
1905  ticketBaiCom.Factura.DatosFactura.AddDetalleFactura(lineaPVerde);
1906  }
1907  }
1908  }
1909 
1910  //Task 185731 => Para Tickets no se soporta la opción de PORTES ni de Dto. Pronto pago que tocaría añadir en este punto
1911 
1912  // Identificadores de clave
1913  string ClaveRegimenIvaOpTrascendencia = (datosTicket._Cabecera._Recc ? "07" : "01");
1914  string ClaveRegimenIvaOpTrascendenciaAdicional = "";
1915 
1916  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando Regimen Especial Trascendencia 01 siempre");
1917  if (string.IsNullOrWhiteSpace(ClaveRegimenIvaOpTrascendenciaAdicional))
1918  {
1919  ticketBaiCom.Factura.DatosFactura.Claves = new IDClaveTypeCom[]
1920  {
1921  new IDClaveTypeCom()
1922  {
1923  ClaveRegimenIvaOpTrascendencia = "Item" + ClaveRegimenIvaOpTrascendencia
1924  },
1925  };
1926  }
1927  else
1928  {
1929  ticketBaiCom.Factura.DatosFactura.Claves = new IDClaveTypeCom[]
1930  {
1931  new IDClaveTypeCom()
1932  {
1933  ClaveRegimenIvaOpTrascendencia = "Item" + ClaveRegimenIvaOpTrascendencia
1934  },
1935  new IDClaveTypeCom()
1936  {
1937  ClaveRegimenIvaOpTrascendencia = "Item" + ClaveRegimenIvaOpTrascendenciaAdicional
1938  },
1939  };
1940  }
1941 
1942  // Tipo desglose
1943  ticketBaiCom.Factura.TipoDesglose = new TipoDesgloseTypeCom();
1944 
1945  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketInternal: Procesando Lineas de IVA Ticket");
1946 
1947  var codes = GetAllSimpleValuesFromJSON(fcTicketRow["IVA"].ToString(), "_Codigo");
1948  var bases = GetAllSimpleValuesFromJSON(fcTicketRow["IVA"].ToString(), "_Base");
1949  var ivas = GetAllSimpleValuesFromJSON(fcTicketRow["IVA"].ToString(), "_PrcIva");
1950  var importes = GetAllSimpleValuesFromJSON(fcTicketRow["IVA"].ToString(), "_ImpIva");
1951  var recargos = GetAllSimpleValuesFromJSON(fcTicketRow["IVA"].ToString(), "_PrcRec");
1952  var importeRecargos = GetAllSimpleValuesFromJSON(fcTicketRow["IVA"].ToString(), "_ImpRec");
1953 
1954  //181416: Si se ha rellenado el IDOtro, solo el hecho de acceder a Item_NIF da una excepcion en el componente. Salvamos el caso con un try/catch
1955  string nifCli = "";
1956  try
1957  {
1958  nifCli = destinatario.Item_NIF;
1959  nifCli = NormalizarCaracteresNif(nifCli);
1960  }
1961  catch { }
1962 
1963  string TipoNoExenta = "";
1964 
1965  for (int i = 0; i < codes.Count; i++)
1966  {
1967  string ivaCode = codes[i];
1968  decimal ivaPrc = Convert.ToDecimal(ivas[i]);
1969 
1970  eTipoOperacionEmitidasSII tipoOpIva = ObtenerTipoOperacionTicket(datosTicket, ivaCode);
1971  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketInternal: TipoOperacionSII obtenido para IVA " + ivaCode + " -> " + tipoOpIva.ToString());
1972 
1973  //Task 185108 => Incorporar casos especiales del SII => En tickets que no guarda destinatario no tiene sentido, lo comento.
1974  //var lnComuni_c = Convert.ToInt32(datosFactura._oCliente._TipoCliente);
1975  var llIvaNoCero = ivaPrc > decimal.Zero;
1976  var ivaPrestacionDeServicios = ObtenerSiiIva303(XML_generator_parameters.NumDocumentoBorrador, "DEV_IS"); //Iva de prestacion de servicios
1977  var llTratamientoNacinal = false; // (nifCli.StartsWith("N") || lnComuni_c == 2 || lnComuni_c == 3) && (llIvaNoCero || ivaPrestacionDeServicios);
1978 
1979  //IVA EUROPEO NO APLICA ya que no tenemos identificado lnComuni_c ni el tipo de operación
1980 
1981  if (((string.IsNullOrWhiteSpace(nifCli) || !nifCli.StartsWith("N")) //Task 186340 => Nifs W no forzamos
1982  && (tipoOpIva == eTipoOperacionEmitidasSII.NacionalNoSujeta ||
1983  tipoOpIva == eTipoOperacionEmitidasSII.NacionalSujetaExenta ||
1984  tipoOpIva == eTipoOperacionEmitidasSII.NacionalSujetaNoExenta) && !llTratamientoNacinal)
1985  // || ((idFiscal == 1 || idFiscal == 0 || idFiscal == 7) && extracomunitario) //Task 187715 =>Tipo documento Nif y Extracomunitario => No tiene sentido en tickets ya que no se informa destinatario
1986  || string.IsNullOrEmpty(nifCli) //Task 187715 => Sin Cif siempre desglose fra.
1987  ) //OPCION 1.Desglose por factura
1988  {
1989  #region Desglose por factura
1990 
1991  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType == null)
1992  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType = new DesgloseFacturaTypeCom();
1993  if (tipoOpIva != eTipoOperacionEmitidasSII.NacionalNoSujeta) //Iva sujeto
1994  {
1995  #region Iva Sujeto
1996 
1997  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta == null)
1998  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta = new SujetaTypeCom();
1999  if (tipoOpIva == eTipoOperacionEmitidasSII.NacionalSujetaExenta) //Iva exento
2000  {
2001  #region Iva exento
2002  if (fcTicketRow["TBEXENTA"] == null || string.IsNullOrWhiteSpace(fcTicketRow["TBEXENTA"].ToString()))
2003  {
2004  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando desglose IVA por factura exento desde columna IVA");
2005 
2006  var detalle = new DetalleExentaTypeCom
2007  {
2008  CausaExencion = "E" + fcTicketRow["TBCASUEX"].ToString().Trim(),
2009  BaseImponible = bases[i].Trim()
2010  };
2011  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.AddExenta(detalle);
2012  }
2013  else
2014  {
2015  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando desglose IVA por factura exento desde columna TBEXENTA");
2016  var causas = GetAllSimpleValuesFromXML(fcTicketRow["TBEXENTA"].ToString(), "causa");
2017  var basesEx = GetAllSimpleValuesFromXML(fcTicketRow["TBEXENTA"].ToString(), "base");
2018  for (int j = 0; j < basesEx.Count; j++)
2019  {
2020  var detalle = new DetalleExentaTypeCom();
2021  if (causas[j] == "7")
2022  detalle.CausaExencion = "E6";
2023  else
2024  detalle.CausaExencion = "E" + causas[j].Trim();
2025  detalle.BaseImponible = basesEx[j].Trim();
2026  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.AddExenta(detalle);
2027  }
2028  }
2029  #endregion Iva exento
2030  }
2031  else //Iva no exento
2032  {
2033  #region Iva no exento
2034  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando desglose IVA por factura regular desde columna IVA");
2035 
2036  //Task 185108
2037  if (ObtenerSiiIva303Ticket(datosTicket, "DEV_IS"))
2038  {
2039  //Bug 186669 => Tipo S3 no aplica en TBAI
2041  //if (!string.IsNullOrWhiteSpace(TipoNoExenta) && TipoNoExenta != "S2")
2042  // TipoNoExenta = "S3";
2043  //else
2044  // TipoNoExenta = "S2";
2045  //Operaciones No habituales. No aplica en tickets
2046  TipoNoExenta = "S2";
2047  }
2048  else
2049  {
2050  //Bug 186669 => Tipo S3 no aplica en TBAI
2052  //if (!string.IsNullOrWhiteSpace(TipoNoExenta) && TipoNoExenta != "S1")
2053  // TipoNoExenta = "S3";
2054  //else
2055  // TipoNoExenta = "S1";
2056  TipoNoExenta = "S1";
2057  }
2058 
2059 
2060 
2061  DetalleNoExentaTypeCom detalle;
2062  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta == null ||
2063  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta.Length == 0 ||
2064  (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta.Length == 1 && ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta[0].TipoNoExenta != TipoNoExenta))
2065  {
2066  detalle = new DetalleNoExentaTypeCom
2067  {
2068  TipoNoExenta = TipoNoExenta
2069  };
2070  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.AddNoExenta(detalle);
2071  }
2072  else
2073  {
2074  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta[0].TipoNoExenta == TipoNoExenta)
2075  detalle = ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta[0] as DetalleNoExentaTypeCom;
2076  else
2077  detalle = ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta[1] as DetalleNoExentaTypeCom;
2078  }
2079 
2080  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Leidas bases de IVA. Rellenando DesgloseIVA componente");
2081 
2082  var detalleIva = new DetalleIVATypeCom
2083  {
2084  BaseImponible = bases[i].Trim(),
2085  TipoImpositivo = ivas[i].Trim(),
2086  CuotaImpuesto = importes[i].Trim()
2087  };
2088 
2089  if (Convert.ToDecimal(recargos[i].Replace('.', ',')) != 0)
2090  {
2091  detalleIva.TipoRecargoEquivalencia = recargos[i].Trim();
2092  detalleIva.CuotaRecargoEquivalencia = importeRecargos[i].Trim();
2093  }
2094  else //Si es 0 hay que mirar que no sea 0% sujeto
2095  {
2096  if (datosTicket._Cabecera._oCliente._Recargo)
2097  {
2098  sage.ew.articulo.TipoIVA tipoIva = new sage.ew.articulo.TipoIVA()
2099  {
2100  _Codigo = codes[i].Trim()
2101  };
2102  if (tipoIva._IVA_Sujeto0)
2103  {
2104  detalleIva.TipoRecargoEquivalencia = recargos[i].Trim();
2105  detalleIva.CuotaRecargoEquivalencia = importeRecargos[i].Trim();
2106  }
2107  }
2108  }
2109  detalleIva.OperacionEnRecargoDeEquivalenciaORegimenSimplificado = "N";
2110  detalleIva.OperacionEnRecargoDeEquivalenciaORegimenSimplificadoSpecified = true;
2111 
2112  detalle.AddDesgloseIVA(detalleIva);
2113 
2114  #endregion Iva no exento
2115  }
2116 
2117  #endregion Iva Sujeto
2118  }
2119  else //Iva no sujeto
2120  {
2121  #region Iva no sujeto
2122 
2123  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando desglose IVA por factura no sujeto desde columna TBNOSUJE");
2124 
2125  var causas = GetAllSimpleValuesFromXML(fcTicketRow["TBNOSUJE"].ToString(), "causa");
2126  var basesNS = GetAllSimpleValuesFromXML(fcTicketRow["TBNOSUJE"].ToString(), "base");
2127 
2128  for (int j = 0; j < basesNS.Count; j++)
2129  {
2130  var detalle = new DetalleNoSujetaCom
2131  {
2132  Causa = (Convert.ToInt16(causas[j]) - 1).ToString().Trim(),
2133  Importe = basesNS[j].ToString().Trim()
2134  };
2135  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.AddNoSujeta(detalle);
2136  }
2137 
2138  #endregion Iva no sujeto
2139  }
2140 
2141  #endregion Desglose por factura
2142  }
2143  else //OPCION 2.Desglose por tipo operación
2144  {
2145  #region Desglose por tipo operación
2146 
2147  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType == null)
2148  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType = new DesgloseTipoOperacionTypeCom();
2149  if (tipoOpIva == eTipoOperacionEmitidasSII.ExtracomunitariaNoSujeta || /*datosTicket._Pie._Iva[0]["IvaServicios"] ||*/
2150  ObtenerSiiIva303Ticket(datosTicket, "DEV_IS")) //Iva de prestacion de servicios
2151  {
2152  #region Iva de prestacion de servicios
2153 
2154  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios == null)
2155  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios = new PrestacionServiciosCom();
2156 
2157  if (tipoOpIva != eTipoOperacionEmitidasSII.NacionalNoSujeta && NifClienteEsEspecialOperaciones(nifCli)) //Iva sujeto // Segun el mapeo no existen de esta tipologia
2158  {
2159  #region Iva sujeto
2160 
2161  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta == null)
2162  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta = new SujetaTypeCom();
2163  if (tipoOpIva == eTipoOperacionEmitidasSII.NacionalSujetaExenta) //Iva exento
2164  {
2165  #region Iva exento
2166  if (fcTicketRow["TBEXENTA"] == null || string.IsNullOrWhiteSpace(fcTicketRow["TBEXENTA"].ToString()))
2167  {
2168  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando desglose IVA prestacion de servicios por factura exento desde columna IVA");
2169 
2170  var detalle = new DetalleExentaTypeCom
2171  {
2172  CausaExencion = "E" + fcTicketRow["TBCASUEX"].ToString().Trim(),
2173  BaseImponible = bases[i].Trim()
2174  };
2175  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.AddExenta(detalle);
2176  }
2177  else
2178  {
2179  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando desglose IVA prestacion de servicios por factura exento desde columna TBEXENTA");
2180  var causas = GetAllSimpleValuesFromXML(fcTicketRow["TBEXENTA"].ToString(), "causa");
2181  var basesEx = GetAllSimpleValuesFromXML(fcTicketRow["TBEXENTA"].ToString(), "base");
2182  for (int j = 0; j < basesEx.Count; j++)
2183  {
2184  var detalle = new DetalleExentaTypeCom();
2185  if (causas[j] == "7")
2186  detalle.CausaExencion = "E6";
2187  else
2188  detalle.CausaExencion = "E" + causas[j].Trim();
2189  detalle.BaseImponible = basesEx[j].Trim();
2190  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.AddExenta(detalle);
2191  }
2192  }
2193  #endregion Iva exento
2194  }
2195  else //Iva no exento
2196  {
2197  #region Iva no exento
2198  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando desglose IVA prestacion de servicios por factura regular desde columna IVA");
2199 
2200  //Task 185108
2201  if (ObtenerSiiIva303Ticket(datosTicket, "DEV_IS"))
2202  {
2203  //Bug 186669 => Tipo S3 no aplica en TBAI
2205  //if (!string.IsNullOrWhiteSpace(TipoNoExenta) && TipoNoExenta != "S2")
2206  // TipoNoExenta = "S3";
2207  //else
2208  // TipoNoExenta = "S2";
2209  //Operaciones No habituales. No aplica en tickets
2210  TipoNoExenta = "S2";
2211  }
2212  else
2213  {
2214  //Bug 186669 => Tipo S3 no aplica en TBAI
2216  //if (!string.IsNullOrWhiteSpace(TipoNoExenta) && TipoNoExenta != "S1")
2217  // TipoNoExenta = "S3";
2218  //else
2219  // TipoNoExenta = "S1";
2220  TipoNoExenta = "S1";
2221  }
2222 
2223  DetalleNoExentaTypeCom detalle;
2224  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta == null ||
2225  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta.Length == 0 ||
2226  (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta.Length == 1 && ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta[0].TipoNoExenta != TipoNoExenta))
2227  {
2228  detalle = new DetalleNoExentaTypeCom
2229  {
2230  TipoNoExenta = TipoNoExenta
2231  };
2232  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.AddNoExenta(detalle);
2233  }
2234  else
2235  {
2236  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta[0].TipoNoExenta == TipoNoExenta)
2237  detalle = ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta[0] as DetalleNoExentaTypeCom;
2238  else
2239  detalle = ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.Sujeta.NoExenta[1] as DetalleNoExentaTypeCom;
2240  }
2241 
2242  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Leidas bases de IVA. Rellenando Desglose IVA prestacion de servicios componente");
2243 
2244  var detalleIva = new DetalleIVATypeCom
2245  {
2246  BaseImponible = bases[i].Trim(),
2247  TipoImpositivo = ivas[i].Trim(),
2248  CuotaImpuesto = importes[i].Trim()
2249  };
2250  if (Convert.ToDecimal(recargos[i].Replace('.', ',')) != 0)
2251  {
2252  detalleIva.TipoRecargoEquivalencia = recargos[i].Trim();
2253  detalleIva.CuotaRecargoEquivalencia = importeRecargos[i].Trim();
2254  }
2255  else //Si es 0 hay que mirar que no sea 0% sujeto
2256  {
2257  if (datosTicket._Cabecera._oCliente._Recargo)
2258  {
2259  sage.ew.articulo.TipoIVA tipoIva = new sage.ew.articulo.TipoIVA()
2260  {
2261  _Codigo = codes[i].Trim()
2262  };
2263  if (tipoIva._IVA_Sujeto0)
2264  {
2265  detalleIva.TipoRecargoEquivalencia = recargos[i].Trim();
2266  detalleIva.CuotaRecargoEquivalencia = importeRecargos[i].Trim();
2267  }
2268  }
2269  }
2270  detalleIva.OperacionEnRecargoDeEquivalenciaORegimenSimplificado = "N";
2271  detalleIva.OperacionEnRecargoDeEquivalenciaORegimenSimplificadoSpecified = true;
2272 
2273  detalle.AddDesgloseIVA(detalleIva);
2274 
2275  #endregion Iva no exento
2276  }
2277 
2278  #endregion Iva sujeto
2279  }
2280  else //Iva no sujeto
2281  {
2282  #region Iva no sujeto
2283 
2284  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando desglose IVA por operacion de servicios no sujeto desde columna TBNOSUJE");
2285  var causas = GetAllSimpleValuesFromXML(fcTicketRow["TBNOSUJE"].ToString(), "causa");
2286  var basesNS = GetAllSimpleValuesFromXML(fcTicketRow["TBNOSUJE"].ToString(), "base");
2287 
2288  for (int j = 0; j < basesNS.Count; j++)
2289  {
2290  var detalle = new DetalleNoSujetaCom
2291  {
2292  Causa = (Convert.ToInt16(causas[j]) - 1).ToString().Trim(),
2293  Importe = basesNS[j].ToString().Trim()
2294  };
2295  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.PrestacionServicios.AddNoSujeta(detalle);
2296  }
2297 
2298  #endregion Iva no sujeto
2299  }
2300 
2301  #endregion Iva de prestacion de servicios
2302  }
2303  else //Iva de entrega de bienes
2304  {
2305  #region Iva de entrega de bienes
2306 
2307  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega == null)
2308  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega = new EntregaCom();
2309  if (tipoOpIva == eTipoOperacionEmitidasSII.NacionalSujetaExenta ||
2310  tipoOpIva == eTipoOperacionEmitidasSII.ComunitariaSujetaExenta ||
2311  tipoOpIva == eTipoOperacionEmitidasSII.ExtracomunitariaSujetaExenta ||
2312  tipoOpIva == eTipoOperacionEmitidasSII.NacionalSujetaNoExenta) //Iva sujeto
2313  {
2314  #region Iva sujeto
2315 
2316  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta == null)
2317  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta = new SujetaTypeCom();
2318 
2319  if (tipoOpIva != eTipoOperacionEmitidasSII.NacionalSujetaNoExenta && NifClienteEsEspecialOperaciones(nifCli)) //Iva exento
2320  {
2321  #region Iva exento
2322 
2323  if (fcTicketRow["TBEXENTA"] == null || string.IsNullOrWhiteSpace(fcTicketRow["TBEXENTA"].ToString()))
2324  {
2325  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando desglose IVA por operacion de bienes exento desde columna IVA");
2326  var detalle = new DetalleExentaTypeCom
2327  {
2328  CausaExencion = "E" + fcTicketRow["TBCASUEX"].ToString().Trim(),
2329  BaseImponible = bases[i].Trim()
2330  };
2331  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.AddExenta(detalle);
2332  }
2333  else
2334  {
2335  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando desglose IVA por operacion de bienes exento desde columna TBEXENTA");
2336  var causas = GetAllSimpleValuesFromXML(fcTicketRow["TBEXENTA"].ToString(), "causa");
2337  var basesEx = GetAllSimpleValuesFromXML(fcTicketRow["TBEXENTA"].ToString(), "base");
2338  for (int j = 0; j < basesEx.Count; j++)
2339  {
2340  var detalle = new DetalleExentaTypeCom();
2341  if (causas[j] == "7")
2342  detalle.CausaExencion = "E6";
2343  else
2344  detalle.CausaExencion = "E" + causas[j].Trim();
2345  detalle.BaseImponible = basesEx[j].Trim();
2346  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.AddExenta(detalle);
2347  }
2348  }
2349 
2350  #endregion Iva exento
2351  }
2352  else //Iva no exento //Segun el mapeo esta tipologia no existe
2353  {
2354 
2355  #region Iva no exento
2356 
2357  //Task 185108
2358  if (ObtenerSiiIva303Ticket(datosTicket, "DEV_IS"))
2359  {
2360  //Bug 186669 => Tipo S3 no aplica en TBAI
2362  //if (!string.IsNullOrWhiteSpace(TipoNoExenta) && TipoNoExenta != "S2")
2363  // TipoNoExenta = "S3";
2364  //else
2365  // TipoNoExenta = "S2";
2366  //Operaciones No habituales. No aplica en tickets
2367  TipoNoExenta = "S2";
2368  }
2369  else
2370  {
2371  //Bug 186669 => Tipo S3 no aplica en TBAI
2373  //if (!string.IsNullOrWhiteSpace(TipoNoExenta) && TipoNoExenta != "S1")
2374  // TipoNoExenta = "S3";
2375  //else
2376  // TipoNoExenta = "S1";
2377  TipoNoExenta = "S1";
2378  }
2379 
2380  DetalleNoExentaTypeCom detalle;
2381  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta == null ||
2382  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta.Length == 0 ||
2383  (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta.Length == 1 && ticketBaiCom.Factura.TipoDesglose.Item_DesgloseFacturaType.Sujeta.NoExenta[0].TipoNoExenta != TipoNoExenta))
2384  {
2385  detalle = new DetalleNoExentaTypeCom
2386  {
2387  TipoNoExenta = TipoNoExenta
2388  };
2389  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.AddNoExenta(detalle);
2390  }
2391  else
2392  {
2393  if (ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta[0].TipoNoExenta == TipoNoExenta)
2394  detalle = ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta[0] as DetalleNoExentaTypeCom;
2395  else
2396  detalle = ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.Sujeta.NoExenta[1] as DetalleNoExentaTypeCom;
2397  }
2398 
2399  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Leidas bases de IVA. Rellenando Desglose IVA entrega de bienes componente");
2400 
2401  var detalleIva = new DetalleIVATypeCom
2402  {
2403  BaseImponible = bases[i].Trim(),
2404  TipoImpositivo = ivas[i].Trim(),
2405  CuotaImpuesto = importes[i].Trim()
2406  };
2407  if (Convert.ToDecimal(recargos[i].Replace('.', ',')) != 0)
2408  {
2409  detalleIva.TipoRecargoEquivalencia = recargos[i].Trim();
2410  detalleIva.CuotaRecargoEquivalencia = importeRecargos[i].Trim();
2411  }
2412  else //Si es 0 hay que mirar que no sea 0% sujeto
2413  {
2414  if (datosTicket._Cabecera._oCliente._Recargo)
2415  {
2416  sage.ew.articulo.TipoIVA tipoIva = new sage.ew.articulo.TipoIVA()
2417  {
2418  _Codigo = codes[i].Trim()
2419  };
2420  if (tipoIva._IVA_Sujeto0)
2421  {
2422  detalleIva.TipoRecargoEquivalencia = recargos[i].Trim();
2423  detalleIva.CuotaRecargoEquivalencia = importeRecargos[i].Trim();
2424  }
2425  }
2426  }
2427  detalleIva.OperacionEnRecargoDeEquivalenciaORegimenSimplificado = "N";
2428  detalleIva.OperacionEnRecargoDeEquivalenciaORegimenSimplificadoSpecified = true;
2429 
2430  detalle.AddDesgloseIVA(detalleIva);
2431 
2432  #endregion Iva no exento
2433 
2434  }
2435 
2436  #endregion Iva sujeto
2437  }
2438  else //Iva no sujeto
2439  {
2440  #region Iva no sujeto
2441 
2442  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Rellenando desglose IVA por operacion de bienes no sujeto desde columna TBNOSUJE");
2443  var causas = GetAllSimpleValuesFromXML(fcTicketRow["TBNOSUJE"].ToString(), "causa");
2444  var basesNS = GetAllSimpleValuesFromXML(fcTicketRow["TBNOSUJE"].ToString(), "base");
2445 
2446  for (int j = 0; j < basesNS.Count; j++)
2447  {
2448  var detalle = new DetalleNoSujetaCom
2449  {
2450  Causa = (Convert.ToInt16(causas[j]) - 1).ToString().Trim(),
2451  Importe = basesNS[j].ToString().Trim()
2452  };
2453  ticketBaiCom.Factura.TipoDesglose.Item_DesgloseTipoOperacionType.Entrega.AddNoSujeta(detalle);
2454  }
2455 
2456  #endregion Iva no sujeto
2457  }
2458 
2459  #endregion Iva de entrega de bienes
2460  }
2461 
2462  #endregion Desglose por tipo operación
2463  }
2464  }
2465 
2466  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Finalizado desglose IVA. Rellenando Huella TBAI");
2467 
2468  // HuellaTBAI
2469  ticketBaiCom.HuellaTBAI = new ComModel.Invoice.V1_0.HuellaTBAICom();
2470 
2471  if (!string.IsNullOrWhiteSpace(XML_generator_parameters.SerieDocumentoAnterior) &&
2472  !string.IsNullOrWhiteSpace(XML_generator_parameters.NumDocumentoAnterior) &&
2473  XML_generator_parameters.FechaDocumentoAnterior.HasValue &&
2474  !string.IsNullOrWhiteSpace(XML_generator_parameters.FirmaDocumentoAnterior))
2475  {
2476  // Encadenamiento factura anterior
2477  ticketBaiCom.HuellaTBAI.EncadenamientoFacturaAnterior = new EncadenamientoFacturaAnteriorTypeCom()
2478  {
2479  SerieFacturaAnterior = string.IsNullOrWhiteSpace(XML_generator_parameters.SerieDocumentoAnterior) ? "" : XML_generator_parameters.SerieDocumentoAnterior.Trim(),
2480  NumFacturaAnterior = string.IsNullOrWhiteSpace(XML_generator_parameters.NumDocumentoAnterior) ? "" : XML_generator_parameters.NumDocumentoAnterior.Trim(),
2481  FechaExpedicionFacturaAnterior = (XML_generator_parameters.FechaDocumentoAnterior.HasValue) ? XML_generator_parameters.FechaDocumentoAnterior.Value.ToString("dd-MM-yyyy") : "",
2482  SignatureValueFirmaFacturaAnterior = XML_generator_parameters.FirmaDocumentoAnterior.Trim()
2483  };
2484  }
2485 
2486  // Software facturacion
2487  ticketBaiCom.HuellaTBAI.Software = Generar_SoftwareFacturacionTypeCom();
2488 
2489  ticketBaiCom.HuellaTBAI.NumSerieDispositivo = TerminalSerialNumber.Trim();
2490  }
2491 
2492  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Creando la instancia del process del componente");
2493  // Generates the xml file, signs and converts to base64 message.
2494  var processObj = _process as object;
2495  CreateProcess(outputFilename, ticketBaiCom.Sujetos.Emisor.Territorio, false, false, ref processObj, Convert.ToDateTime(ticketBaiCom.Factura.CabeceraFactura.FechaExpedicionFactura));
2496  if (_process != null)
2497  {
2498  _process.TicketBaiCom_V1_0 = ticketBaiCom;
2499  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Generando el XML desde el componente");
2500  if (_process.GenerateCom())
2501  {
2502  ErrorMessage = "";
2503  GeneratedSignature = _process.SignatureString;
2504  GeneratedTBaiCode = _process.GetStringTBAI;
2505  GeneratedTBaiQR = _process.GetStringQR;
2506  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Todo correcto, devolviendo datos.");
2507  //180350
2508  FacturasCreadasEstaSesionSinEnviar.Add(datosTicket._Letra + datosTicket._Numero);
2509  return true;
2510  }
2511  else
2512  {
2513  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Componente devuelve error." + _process.MsgError);
2514  ErrorMessage = "Proceso de generación terminado con incidencias. Consulta el fichero de Log para ver los detalles." + Environment.NewLine +
2515  Environment.NewLine + "Error: " + _process.MsgError.Trim();
2516  }
2517  }
2518  }
2519  catch (Exception ex)
2520  {
2521  GenerateTrace("ExportadorFactuCertXML.GenerateTicketBaiDataTicketsInternal: Excepción durante la generación." + ex.Message);
2522  DB.Registrar_Error(ex);
2523  ErrorMessage = "Error durante el proceso de generación. Mensaje: " + ex.Message;
2524  }
2525  finally
2526  {
2527  if (ticketBaiCom != null)
2528  {
2529  ticketBaiCom.Dispose();
2530  ticketBaiCom = null;
2531  }
2532  }
2533 
2534  return false;
2535  }
2536 
2543  private bool GenerateAnulationDataInternal(string outputFilename, HuellaDetalle huellaFraOriginal)
2544  {
2545 
2546  // Objects of COM model.
2547  AnulaTicketBaiCom anulaTicketBaiCom = null;
2548  GeneratedSignature = "";
2549 
2550  var nifEmisor = NormalizarCaracteresNif(((ew.empresa.Empresa)EW_GLOBAL._Empresa)._CifTC);
2551 
2552  try
2553  {
2554 
2555  #region Generar objeto COM Anulación
2556 
2557  // TicketBai
2558  anulaTicketBaiCom = new AnulaTicketBaiCom()
2559  {
2560  // Cabecera
2561  Cabecera = new CabeceraCom()
2562  {
2563  IDVersionTBAI = "1.2"
2564  },
2565  IDFactura = new IDFacturaCom()
2566  {
2567  // Emisor
2568  Emisor = new EmisorCom()
2569  {
2570  NIF = nifEmisor,
2571  ApellidosNombreRazonSocial = ((ew.empresa.Empresa)EW_GLOBAL._Empresa)._ApellidosTC + " " + ((ew.empresa.Empresa)EW_GLOBAL._Empresa)._NombreTC.Trim()
2572  },
2573  // Cabecera factura
2574  CabeceraFactura = new ComModel.Annulation.V1_0.CabeceraFacturaTypeCom()
2575  {
2576  SerieFactura = huellaFraOriginal.serie.TrimEnd(),
2577  NumFactura = huellaFraOriginal.documento.TrimEnd(),
2578  FechaExpedicionFactura = Convert.ToDateTime(huellaFraOriginal.fecha).ToString("dd-MM-yyyy")
2579  }
2580  },
2581 
2582  // HuellaTBAI
2583  HuellaTBAI = new ComModel.Annulation.V1_0.HuellaTBAICom()
2584  {
2585  // Software facturacion
2586  Software = Generar_SoftwareFacturacionTypeCom(),
2587  NumSerieDispositivo = TerminalSerialNumber.Trim()
2588  }
2589  };
2590 
2591  #endregion Generar objeto COM Anulación
2592 
2593  #region Obtener la firma del componente
2594 
2595  //Creamos el proceso con el parámetro isCancellation = true
2596  var processObj = _process as object;
2597  CreateProcess(outputFilename, GetTerritorioEnvioTBai(true), false, true, ref processObj, Convert.ToDateTime(anulaTicketBaiCom.IDFactura.CabeceraFactura.FechaExpedicionFactura));
2598  if (_process != null)
2599  {
2600  // Generates the xml file, signs and converts to base64 message.
2601  // Si todo va bien => euroserv\modulos\factucert\CodigoGrupo\CodigoEmpresa\ANULADOS
2602  _process.AnulaTicketBaiCom_V1_0 = anulaTicketBaiCom;
2603  if (_process.GenerateCom())
2604  {
2605  ErrorMessage = "";
2606  GeneratedSignature = _process.SignatureString;
2607  GeneratedTBaiCode = _process.GetStringTBAI;
2608  GeneratedTBaiQR = _process.GetStringQR;
2609 
2610  GenerateTrace("ExportadorFactuCertXML.GenerateAnulationDataInternal: Todo correcto, devolviendo datos.");
2611  return true;
2612  }
2613  else
2614  {
2615  GenerateTrace("ExportadorFactuCertXML.GenerateAnulationDataInternal: Componente devuelve error." + _process.MsgError);
2616  ErrorMessage = "Proceso de generación terminado con incidencias. Consulta el fichero de Log para ver los detalles." + Environment.NewLine + Environment.NewLine + "Error: " + _process.MsgError.Trim();
2617  }
2618  }
2619 
2620  #endregion Obtener la firma del componente
2621  }
2622  catch (Exception ex)
2623  {
2624  DB.Registrar_Error(ex);
2625  ErrorMessage = "Error durante el proceso de anulación. Mensaje: " + ex.Message;
2626  }
2627  finally
2628  {
2629  if (anulaTicketBaiCom != null)
2630  {
2631  anulaTicketBaiCom.Dispose();
2632  }
2633  }
2634 
2635  return false;
2636  }
2637  }
2638 }
virtual string _Numero
Número del document
Definition: DocsVen.cs:2356
override string _Factura
Sobreescribimos la propiedad _Factura pues al cambiar su valor en funcion de si estamos en ventas o e...
bool _IvaIncluido
Flag para controlar si se trabaja con IVA INCLUIDO o no.
Este es el espacio de nombres de su módulo. Puede encontrar más información y ayuda en el fichero rea...
BindingList< TipoIvaLinea > _TipoIvaLineas
Lista de tipos de IVA de la factura que se está generando.
Clase documento de venta TPV
Definition: DocVentaTpv.cs:47
Clase de negocio para Listado de retención soportada
Clase DTO para representar datos de facturas rectificativas
Es como el tipo de entrada asientos pero por negocio, sin formulario, pq quiero que me haga las propu...
virtual string _Letra
Lletra
Definition: DocsVen.cs:2340
Clase DTO para representar datos de facturas rectificativas
eTipoOperacionEmitidasSII
Enumeración con los distintos tipos de operaciones en el libro de facturas emitidas del SII ...
DateTime _Fecha
Fecha del documento (se crea por compatibilidad con la interficie IDivisaOperable ...
_TipoDocCab _Cabecera
Cabecera
Definition: DocsVen.cs:2626
BindingList< _TipoDocLin > _Lineas
Líneas
Definition: DocsVen.cs:2646
DateTime _Fecha
Fecha del documento
Definition: DocsVen.cs:11760
string _Nombre
Nombre del cliente o proveedor según si estamos en generador de asientos de facturas de venta o de co...
Clase de negocio para generador de asientos de factura de venta, deriva de la clase AsientosFacturasG...
Código(Cliente, Cuenta, Proveedor)
decimal _TotalRecFinan
Importe total de recargo financiero.
bool _Recc
Regimen especial de criterio de caja