diff --git a/EmtusaHuelva.slnx b/EmtusaHuelva.slnx
index ca09226..e156812 100644
--- a/EmtusaHuelva.slnx
+++ b/EmtusaHuelva.slnx
@@ -1,3 +1,4 @@
+
diff --git a/bdEmtusa/Class1.cs b/bdEmtusa/Class1.cs
deleted file mode 100644
index e24b9a4..0000000
--- a/bdEmtusa/Class1.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace bdEmtusa
-{
- public class Class1
- {
-
- }
-}
diff --git a/bdEmtusa/CodeTemplates/EFCore/DbContext.t4 b/bdEmtusa/CodeTemplates/EFCore/DbContext.t4
new file mode 100644
index 0000000..fb6faca
--- /dev/null
+++ b/bdEmtusa/CodeTemplates/EFCore/DbContext.t4
@@ -0,0 +1,360 @@
+<#@ template hostSpecific="true" #>
+<#@ assembly name="Microsoft.EntityFrameworkCore" #>
+<#@ assembly name="Microsoft.EntityFrameworkCore.Design" #>
+<#@ assembly name="Microsoft.EntityFrameworkCore.Relational" #>
+<#@ assembly name="Microsoft.Extensions.DependencyInjection.Abstractions" #>
+<#@ parameter name="Model" type="Microsoft.EntityFrameworkCore.Metadata.IModel" #>
+<#@ parameter name="Options" type="Microsoft.EntityFrameworkCore.Scaffolding.ModelCodeGenerationOptions" #>
+<#@ parameter name="NamespaceHint" type="System.String" #>
+<#@ import namespace="System.Collections.Generic" #>
+<#@ import namespace="System.Linq" #>
+<#@ import namespace="System.Text" #>
+<#@ import namespace="Microsoft.EntityFrameworkCore" #>
+<#@ import namespace="Microsoft.EntityFrameworkCore.Design" #>
+<#@ import namespace="Microsoft.EntityFrameworkCore.Infrastructure" #>
+<#@ import namespace="Microsoft.EntityFrameworkCore.Scaffolding" #>
+<#@ import namespace="Microsoft.Extensions.DependencyInjection" #>
+<#
+ // Template version: 800 - please do NOT remove this line
+ if (!ProductInfo.GetVersion().StartsWith("8.0"))
+ {
+ Warning("Your templates were created using an older version of Entity Framework. Additional features and bug fixes may be available. See https://aka.ms/efcore-docs-updating-templates for more information.");
+ }
+
+ var services = (IServiceProvider)Host;
+ var providerCode = services.GetRequiredService();
+ var annotationCodeGenerator = services.GetRequiredService();
+ var code = services.GetRequiredService();
+
+ var usings = new List
+ {
+ "System",
+ "System.Collections.Generic",
+ "Microsoft.EntityFrameworkCore"
+ };
+
+ if (NamespaceHint != Options.ModelNamespace
+ && !string.IsNullOrEmpty(Options.ModelNamespace))
+ {
+ usings.Add(Options.ModelNamespace);
+ }
+
+ if (!string.IsNullOrEmpty(NamespaceHint))
+ {
+#>
+namespace <#= NamespaceHint #>;
+
+<#
+ }
+#>
+public partial class <#= Options.ContextName #> : DbContext
+{
+<#
+ if (!Options.SuppressOnConfiguring)
+ {
+#>
+ public <#= Options.ContextName #>()
+ {
+ }
+
+<#
+ }
+#>
+ public <#= Options.ContextName #>(DbContextOptions<<#= Options.ContextName #>> options)
+ : base(options)
+ {
+ }
+
+<#
+ foreach (var entityType in Model.GetEntityTypes().Where(e => !e.IsSimpleManyToManyJoinEntityType()))
+ {
+#>
+ public virtual DbSet<<#= entityType.Name #>> <#= entityType.GetDbSetName() #> { get; set; }
+
+<#
+ }
+
+ if (!Options.SuppressOnConfiguring)
+ {
+#>
+ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+<#
+ if (!Options.SuppressConnectionStringWarning)
+ {
+#>
+#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
+<#
+ }
+#>
+ => optionsBuilder<#= code.Fragment(providerCode.GenerateUseProvider(Options.ConnectionString), indent: 3) #>;
+
+<#
+ }
+
+#>
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+<#
+ var anyConfiguration = false;
+
+ var modelFluentApiCalls = Model.GetFluentApiCalls(annotationCodeGenerator);
+ if (modelFluentApiCalls != null)
+ {
+ usings.AddRange(modelFluentApiCalls.GetRequiredUsings());
+#>
+ modelBuilder<#= code.Fragment(modelFluentApiCalls, indent: 3) #>;
+<#
+ anyConfiguration = true;
+ }
+
+ StringBuilder mainEnvironment;
+ foreach (var entityType in Model.GetEntityTypes().Where(e => !e.IsSimpleManyToManyJoinEntityType()))
+ {
+ // Save all previously generated code, and start generating into a new temporary environment
+ mainEnvironment = GenerationEnvironment;
+ GenerationEnvironment = new StringBuilder();
+
+ if (anyConfiguration)
+ {
+ WriteLine("");
+ }
+
+ var anyEntityTypeConfiguration = false;
+#>
+ modelBuilder.Entity<<#= entityType.Name #>>(entity =>
+ {
+<#
+ var key = entityType.FindPrimaryKey();
+ if (key != null)
+ {
+ var keyFluentApiCalls = key.GetFluentApiCalls(annotationCodeGenerator);
+ if (keyFluentApiCalls != null
+ || (!key.IsHandledByConvention() && !Options.UseDataAnnotations))
+ {
+ if (keyFluentApiCalls != null)
+ {
+ usings.AddRange(keyFluentApiCalls.GetRequiredUsings());
+ }
+#>
+ entity.HasKey(<#= code.Lambda(key.Properties, "e") #>)<#= code.Fragment(keyFluentApiCalls, indent: 4) #>;
+<#
+ anyEntityTypeConfiguration = true;
+ }
+ }
+
+ var entityTypeFluentApiCalls = entityType.GetFluentApiCalls(annotationCodeGenerator)
+ ?.FilterChain(c => !(Options.UseDataAnnotations && c.IsHandledByDataAnnotations));
+ if (entityTypeFluentApiCalls != null)
+ {
+ usings.AddRange(entityTypeFluentApiCalls.GetRequiredUsings());
+
+ if (anyEntityTypeConfiguration)
+ {
+ WriteLine("");
+ }
+#>
+ entity<#= code.Fragment(entityTypeFluentApiCalls, indent: 4) #>;
+<#
+ anyEntityTypeConfiguration = true;
+ }
+
+ foreach (var index in entityType.GetIndexes()
+ .Where(i => !(Options.UseDataAnnotations && i.IsHandledByDataAnnotations(annotationCodeGenerator))))
+ {
+ if (anyEntityTypeConfiguration)
+ {
+ WriteLine("");
+ }
+
+ var indexFluentApiCalls = index.GetFluentApiCalls(annotationCodeGenerator);
+ if (indexFluentApiCalls != null)
+ {
+ usings.AddRange(indexFluentApiCalls.GetRequiredUsings());
+ }
+#>
+ entity.HasIndex(<#= code.Lambda(index.Properties, "e") #>, <#= code.Literal(index.GetDatabaseName()) #>)<#= code.Fragment(indexFluentApiCalls, indent: 4) #>;
+<#
+ anyEntityTypeConfiguration = true;
+ }
+
+ var firstProperty = true;
+ foreach (var property in entityType.GetProperties())
+ {
+ var propertyFluentApiCalls = property.GetFluentApiCalls(annotationCodeGenerator)
+ ?.FilterChain(c => !(Options.UseDataAnnotations && c.IsHandledByDataAnnotations)
+ && !(c.Method == "IsRequired" && Options.UseNullableReferenceTypes && !property.ClrType.IsValueType));
+ if (propertyFluentApiCalls == null)
+ {
+ continue;
+ }
+
+ usings.AddRange(propertyFluentApiCalls.GetRequiredUsings());
+
+ if (anyEntityTypeConfiguration && firstProperty)
+ {
+ WriteLine("");
+ }
+#>
+ entity.Property(e => e.<#= property.Name #>)<#= code.Fragment(propertyFluentApiCalls, indent: 4) #>;
+<#
+ anyEntityTypeConfiguration = true;
+ firstProperty = false;
+ }
+
+ foreach (var foreignKey in entityType.GetForeignKeys())
+ {
+ var foreignKeyFluentApiCalls = foreignKey.GetFluentApiCalls(annotationCodeGenerator)
+ ?.FilterChain(c => !(Options.UseDataAnnotations && c.IsHandledByDataAnnotations));
+ if (foreignKeyFluentApiCalls == null)
+ {
+ continue;
+ }
+
+ usings.AddRange(foreignKeyFluentApiCalls.GetRequiredUsings());
+
+ if (anyEntityTypeConfiguration)
+ {
+ WriteLine("");
+ }
+#>
+ entity.HasOne(d => d.<#= foreignKey.DependentToPrincipal.Name #>).<#= foreignKey.IsUnique ? "WithOne" : "WithMany" #>(<#= foreignKey.PrincipalToDependent != null ? $"p => p.{foreignKey.PrincipalToDependent.Name}" : "" #>)<#= code.Fragment(foreignKeyFluentApiCalls, indent: 4) #>;
+<#
+ anyEntityTypeConfiguration = true;
+ }
+
+ foreach (var skipNavigation in entityType.GetSkipNavigations().Where(n => n.IsLeftNavigation()))
+ {
+ if (anyEntityTypeConfiguration)
+ {
+ WriteLine("");
+ }
+
+ var left = skipNavigation.ForeignKey;
+ var leftFluentApiCalls = left.GetFluentApiCalls(annotationCodeGenerator, useStrings: true);
+ var right = skipNavigation.Inverse.ForeignKey;
+ var rightFluentApiCalls = right.GetFluentApiCalls(annotationCodeGenerator, useStrings: true);
+ var joinEntityType = skipNavigation.JoinEntityType;
+
+ if (leftFluentApiCalls != null)
+ {
+ usings.AddRange(leftFluentApiCalls.GetRequiredUsings());
+ }
+
+ if (rightFluentApiCalls != null)
+ {
+ usings.AddRange(rightFluentApiCalls.GetRequiredUsings());
+ }
+#>
+ entity.HasMany(d => d.<#= skipNavigation.Name #>).WithMany(p => p.<#= skipNavigation.Inverse.Name #>)
+ .UsingEntity>(
+ <#= code.Literal(joinEntityType.Name) #>,
+ r => r.HasOne<<#= right.PrincipalEntityType.Name #>>().WithMany()<#= code.Fragment(rightFluentApiCalls, indent: 6) #>,
+ l => l.HasOne<<#= left.PrincipalEntityType.Name #>>().WithMany()<#= code.Fragment(leftFluentApiCalls, indent: 6) #>,
+ j =>
+ {
+<#
+ var joinKey = joinEntityType.FindPrimaryKey();
+ var joinKeyFluentApiCalls = joinKey.GetFluentApiCalls(annotationCodeGenerator);
+
+ if (joinKeyFluentApiCalls != null)
+ {
+ usings.AddRange(joinKeyFluentApiCalls.GetRequiredUsings());
+ }
+#>
+ j.HasKey(<#= code.Arguments(joinKey.Properties.Select(e => e.Name)) #>)<#= code.Fragment(joinKeyFluentApiCalls, indent: 7) #>;
+<#
+ var joinEntityTypeFluentApiCalls = joinEntityType.GetFluentApiCalls(annotationCodeGenerator);
+ if (joinEntityTypeFluentApiCalls != null)
+ {
+ usings.AddRange(joinEntityTypeFluentApiCalls.GetRequiredUsings());
+#>
+ j<#= code.Fragment(joinEntityTypeFluentApiCalls, indent: 7) #>;
+<#
+ }
+
+ foreach (var index in joinEntityType.GetIndexes())
+ {
+ var indexFluentApiCalls = index.GetFluentApiCalls(annotationCodeGenerator);
+ if (indexFluentApiCalls != null)
+ {
+ usings.AddRange(indexFluentApiCalls.GetRequiredUsings());
+ }
+#>
+ j.HasIndex(<#= code.Literal(index.Properties.Select(e => e.Name).ToArray()) #>, <#= code.Literal(index.GetDatabaseName()) #>)<#= code.Fragment(indexFluentApiCalls, indent: 7) #>;
+<#
+ }
+
+ foreach (var property in joinEntityType.GetProperties())
+ {
+ var propertyFluentApiCalls = property.GetFluentApiCalls(annotationCodeGenerator);
+ if (propertyFluentApiCalls == null)
+ {
+ continue;
+ }
+
+ usings.AddRange(propertyFluentApiCalls.GetRequiredUsings());
+#>
+ j.IndexerProperty<<#= code.Reference(property.ClrType) #>>(<#= code.Literal(property.Name) #>)<#= code.Fragment(propertyFluentApiCalls, indent: 7) #>;
+<#
+ }
+#>
+ });
+<#
+ anyEntityTypeConfiguration = true;
+ }
+#>
+ });
+<#
+ // If any signicant code was generated, append it to the main environment
+ if (anyEntityTypeConfiguration)
+ {
+ mainEnvironment.Append(GenerationEnvironment);
+ anyConfiguration = true;
+ }
+
+ // Resume generating code into the main environment
+ GenerationEnvironment = mainEnvironment;
+ }
+
+ foreach (var sequence in Model.GetSequences())
+ {
+ var needsType = sequence.Type != typeof(long);
+ var needsSchema = !string.IsNullOrEmpty(sequence.Schema) && sequence.Schema != sequence.Model.GetDefaultSchema();
+ var sequenceFluentApiCalls = sequence.GetFluentApiCalls(annotationCodeGenerator);
+#>
+ modelBuilder.HasSequence<#= needsType ? $"<{code.Reference(sequence.Type)}>" : "" #>(<#= code.Literal(sequence.Name) #><#= needsSchema ? $", {code.Literal(sequence.Schema)}" : "" #>)<#= code.Fragment(sequenceFluentApiCalls, indent: 3) #>;
+<#
+ }
+
+ if (anyConfiguration)
+ {
+ WriteLine("");
+ }
+#>
+ OnModelCreatingPartial(modelBuilder);
+ }
+
+ partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
+}
+<#
+ mainEnvironment = GenerationEnvironment;
+ GenerationEnvironment = new StringBuilder();
+
+ WriteLine("// This file has been auto generated by EF Core Power Tools. ");
+ if (Options.UseNullableReferenceTypes)
+ {
+ WriteLine("#nullable enable");
+ }
+ WriteLine("");
+
+ foreach (var ns in usings.Distinct().OrderBy(x => x, new NamespaceComparer()))
+ {
+#>
+using <#= ns #>;
+<#
+ }
+
+ WriteLine("");
+
+ GenerationEnvironment.Append(mainEnvironment);
+#>
diff --git a/bdEmtusa/CodeTemplates/EFCore/EntityType.t4 b/bdEmtusa/CodeTemplates/EFCore/EntityType.t4
new file mode 100644
index 0000000..c5bc790
--- /dev/null
+++ b/bdEmtusa/CodeTemplates/EFCore/EntityType.t4
@@ -0,0 +1,181 @@
+<#@ template hostSpecific="true" #>
+<#@ assembly name="Microsoft.EntityFrameworkCore" #>
+<#@ assembly name="Microsoft.EntityFrameworkCore.Design" #>
+<#@ assembly name="Microsoft.EntityFrameworkCore.Relational" #>
+<#@ assembly name="Microsoft.Extensions.DependencyInjection.Abstractions" #>
+<#@ parameter name="EntityType" type="Microsoft.EntityFrameworkCore.Metadata.IEntityType" #>
+<#@ parameter name="Options" type="Microsoft.EntityFrameworkCore.Scaffolding.ModelCodeGenerationOptions" #>
+<#@ parameter name="NamespaceHint" type="System.String" #>
+<#@ import namespace="System.Collections.Generic" #>
+<#@ import namespace="System.ComponentModel.DataAnnotations" #>
+<#@ import namespace="System.Linq" #>
+<#@ import namespace="System.Text" #>
+<#@ import namespace="Microsoft.EntityFrameworkCore" #>
+<#@ import namespace="Microsoft.EntityFrameworkCore.Design" #>
+<#@ import namespace="Microsoft.Extensions.DependencyInjection" #>
+<#
+ // Template version: 800 - please do NOT remove this line
+ if (EntityType.IsSimpleManyToManyJoinEntityType())
+ {
+ // Don't scaffold these
+ return "";
+ }
+
+ var services = (IServiceProvider)Host;
+ var annotationCodeGenerator = services.GetRequiredService();
+ var code = services.GetRequiredService();
+
+ var usings = new List
+ {
+ "System",
+ "System.Collections.Generic"
+ };
+
+ if (Options.UseDataAnnotations)
+ {
+ usings.Add("System.ComponentModel.DataAnnotations");
+ usings.Add("System.ComponentModel.DataAnnotations.Schema");
+ usings.Add("Microsoft.EntityFrameworkCore");
+ }
+
+ if (!string.IsNullOrEmpty(NamespaceHint))
+ {
+#>
+namespace <#= NamespaceHint #>;
+
+<#
+ }
+
+ if (!string.IsNullOrEmpty(EntityType.GetComment()))
+ {
+#>
+///
+/// <#= code.XmlComment(EntityType.GetComment()) #>
+///
+<#
+ }
+
+ if (Options.UseDataAnnotations)
+ {
+ foreach (var dataAnnotation in EntityType.GetDataAnnotations(annotationCodeGenerator))
+ {
+#>
+<#= code.Fragment(dataAnnotation) #>
+<#
+ }
+ }
+#>
+public partial class <#= EntityType.Name #>
+{
+<#
+ var firstProperty = true;
+ foreach (var property in EntityType.GetProperties().OrderBy(p => p.GetColumnOrder() ?? -1))
+ {
+ if (!firstProperty)
+ {
+ WriteLine("");
+ }
+
+ if (!string.IsNullOrEmpty(property.GetComment()))
+ {
+#>
+ ///
+ /// <#= code.XmlComment(property.GetComment(), indent: 1) #>
+ ///
+<#
+ }
+
+ if (Options.UseDataAnnotations)
+ {
+ var dataAnnotations = property.GetDataAnnotations(annotationCodeGenerator)
+ .Where(a => !(a.Type == typeof(RequiredAttribute) && Options.UseNullableReferenceTypes && !property.ClrType.IsValueType));
+ foreach (var dataAnnotation in dataAnnotations)
+ {
+#>
+ <#= code.Fragment(dataAnnotation) #>
+<#
+ }
+ }
+
+ usings.AddRange(code.GetRequiredUsings(property.ClrType));
+
+ var needsNullable = Options.UseNullableReferenceTypes && property.IsNullable && !property.ClrType.IsValueType;
+ var needsInitializer = Options.UseNullableReferenceTypes && !property.IsNullable && !property.ClrType.IsValueType;
+#>
+ public <#= code.Reference(property.ClrType) #><#= needsNullable ? "?" : "" #> <#= property.Name #> { get; set; }<#= needsInitializer ? " = null!;" : "" #>
+<#
+ firstProperty = false;
+ }
+
+ foreach (var navigation in EntityType.GetNavigations())
+ {
+ WriteLine("");
+
+ if (Options.UseDataAnnotations)
+ {
+ foreach (var dataAnnotation in navigation.GetDataAnnotations(annotationCodeGenerator))
+ {
+#>
+ <#= code.Fragment(dataAnnotation) #>
+<#
+ }
+ }
+
+ var targetType = navigation.TargetEntityType.Name;
+ if (navigation.IsCollection)
+ {
+#>
+ public virtual ICollection<<#= targetType #>> <#= navigation.Name #> { get; set; } = new List<<#= targetType #>>();
+<#
+ }
+ else
+ {
+ var needsNullable = Options.UseNullableReferenceTypes && !(navigation.ForeignKey.IsRequired && navigation.IsOnDependent);
+ var needsInitializer = Options.UseNullableReferenceTypes && navigation.ForeignKey.IsRequired && navigation.IsOnDependent;
+#>
+ public virtual <#= targetType #><#= needsNullable ? "?" : "" #> <#= navigation.Name #> { get; set; }<#= needsInitializer ? " = null!;" : "" #>
+<#
+ }
+ }
+
+ foreach (var skipNavigation in EntityType.GetSkipNavigations())
+ {
+ WriteLine("");
+
+ if (Options.UseDataAnnotations)
+ {
+ foreach (var dataAnnotation in skipNavigation.GetDataAnnotations(annotationCodeGenerator))
+ {
+#>
+ <#= code.Fragment(dataAnnotation) #>
+<#
+ }
+ }
+#>
+ public virtual ICollection<<#= skipNavigation.TargetEntityType.Name #>> <#= skipNavigation.Name #> { get; set; } = new List<<#= skipNavigation.TargetEntityType.Name #>>();
+<#
+ }
+#>
+}
+<#
+ var previousOutput = GenerationEnvironment;
+ GenerationEnvironment = new StringBuilder();
+
+ WriteLine("// This file has been auto generated by EF Core Power Tools. ");
+ if (Options.UseNullableReferenceTypes)
+ {
+ WriteLine("#nullable enable");
+ }
+ WriteLine("");
+
+ foreach (var ns in usings.Distinct().OrderBy(x => x, new NamespaceComparer()))
+ {
+#>
+using <#= ns #>;
+<#
+ }
+
+ WriteLine("");
+
+ GenerationEnvironment.Append(previousOutput);
+#>
diff --git a/bdEmtusa/FodyWeavers.xml b/bdEmtusa/FodyWeavers.xml
new file mode 100644
index 0000000..d5abfed
--- /dev/null
+++ b/bdEmtusa/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/bdEmtusa/Utilidades.cs b/bdEmtusa/Utilidades.cs
new file mode 100644
index 0000000..bc54ff0
--- /dev/null
+++ b/bdEmtusa/Utilidades.cs
@@ -0,0 +1,59 @@
+using bdEmtusa.db;
+using bdEmtusa.dbcontext;
+using Microsoft.VisualBasic;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+namespace bdEmtusa
+{
+
+
+ public class Utilidades
+ {
+
+
+ public static string? VersionPrograma { get; set; }
+ // public static double PorcentajeIva { get; set; }
+
+
+ public static void GeneraNotificacion(tsUtilidades.TsNotificacionesClient.TipoNotificacionEnum Tipo, string Titulo, string? Cuerpo=null, Exception? ex=null, byte[]? FicheroImagen = null, [CallerMemberName] string? Caller = null)
+ {
+ try
+ {
+ string sMensaje = ((VersionPrograma != null ? "Versión Programa: " + VersionPrograma : "")
+ + (Caller != null ? " Rutina: " + Caller : "")
+ + (Cuerpo != null ? Cuerpo : Titulo)
+ ).Trim();
+ if (ex != null)
+ {
+
+ string sStackTrace = "Tipo excepción: " + ex.ToString() + Constants.vbCrLf;
+ var exError = ex;
+ do
+ {
+ sStackTrace += exError.StackTrace + Constants.vbCrLf;
+ exError = exError.InnerException;
+ }
+ while (exError != null);
+ if (!string.IsNullOrEmpty(sStackTrace))
+ sMensaje += Constants.vbCrLf + "StackTrace: " + sStackTrace;
+ }
+ if (FicheroImagen is null)
+ {
+ tsUtilidades.TsNotificacionesClient.RegistrarAsync(Titulo, sMensaje, Tipo);
+ }
+ else
+ {
+ tsUtilidades.TsNotificacionesClient.RegistrarAsync(Titulo, sMensaje, Tipo, FicheroImagen);
+ }
+ }
+ catch (Exception ex2)
+ {
+ throw new Exception(ex2.Message, ex2);
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/bdEmtusa/bdEmtusa.csproj b/bdEmtusa/bdEmtusa.csproj
index fa71b7a..0eb837a 100644
--- a/bdEmtusa/bdEmtusa.csproj
+++ b/bdEmtusa/bdEmtusa.csproj
@@ -6,4 +6,16 @@
enable
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bdEmtusa/db/channels.cs b/bdEmtusa/db/channels.cs
new file mode 100644
index 0000000..1724ec1
--- /dev/null
+++ b/bdEmtusa/db/channels.cs
@@ -0,0 +1,34 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable enable
+
+using System;
+using System.Collections.Generic;
+
+namespace bdEmtusa.db;
+
+public partial class channels
+{
+ public uint id { get; set; }
+
+ public DateTime? creacion { get; set; }
+
+ public DateTime? modificacion { get; set; }
+
+ public uint n_modificaciones { get; set; }
+
+ public string? title { get; set; }
+
+ public string? description { get; set; }
+
+ public string? link { get; set; }
+
+ public DateTime? lastBuildDate { get; set; }
+
+ public string? generator { get; set; }
+
+ public string? language { get; set; }
+
+ public bool oculto { get; set; }
+
+ public virtual ICollection items { get; set; } = new List();
+}
diff --git a/bdEmtusa/db/configuracion.cs b/bdEmtusa/db/configuracion.cs
new file mode 100644
index 0000000..a319e64
--- /dev/null
+++ b/bdEmtusa/db/configuracion.cs
@@ -0,0 +1,18 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable enable
+
+using System;
+using System.Collections.Generic;
+
+namespace bdEmtusa.db;
+
+public partial class configuracion
+{
+ public int id { get; set; }
+
+ public string codigo { get; set; } = null!;
+
+ public string? grupo { get; set; }
+
+ public string? valor { get; set; }
+}
diff --git a/bdEmtusa/db/historico.cs b/bdEmtusa/db/historico.cs
new file mode 100644
index 0000000..3b59103
--- /dev/null
+++ b/bdEmtusa/db/historico.cs
@@ -0,0 +1,20 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable enable
+
+using System;
+using System.Collections.Generic;
+
+namespace bdEmtusa.db;
+
+public partial class historico
+{
+ public uint id { get; set; }
+
+ public DateTime? fechaHora { get; set; }
+
+ public uint? id_channel { get; set; }
+
+ public uint? id_item { get; set; }
+
+ public string? descripcion { get; set; }
+}
diff --git a/bdEmtusa/db/items.cs b/bdEmtusa/db/items.cs
new file mode 100644
index 0000000..d7581f5
--- /dev/null
+++ b/bdEmtusa/db/items.cs
@@ -0,0 +1,38 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable enable
+
+using System;
+using System.Collections.Generic;
+
+namespace bdEmtusa.db;
+
+public partial class items
+{
+ public uint id { get; set; }
+
+ public uint? id_channel { get; set; }
+
+ public DateTime? creacion { get; set; }
+
+ public DateTime? modificacion { get; set; }
+
+ public uint n_modificaciones { get; set; }
+
+ public string? title { get; set; }
+
+ public string? link { get; set; }
+
+ public string? guid { get; set; }
+
+ public bool? guidIsPermaLink { get; set; }
+
+ public string? description { get; set; }
+
+ public string? category { get; set; }
+
+ public DateTime? pubDate { get; set; }
+
+ public bool oculto { get; set; }
+
+ public virtual channels? id_channelNavigation { get; set; }
+}
diff --git a/bdEmtusa/dbcontext/EmtusaContext.cs b/bdEmtusa/dbcontext/EmtusaContext.cs
new file mode 100644
index 0000000..0454d67
--- /dev/null
+++ b/bdEmtusa/dbcontext/EmtusaContext.cs
@@ -0,0 +1,105 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable enable
+
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore;
+using bdEmtusa.db;
+
+namespace bdEmtusa.dbcontext;
+
+public partial class EmtusaContext : DbContext
+{
+ public EmtusaContext(DbContextOptions options)
+ : base(options)
+ {
+ }
+
+ public virtual DbSet channels { get; set; }
+
+ public virtual DbSet configuracion { get; set; }
+
+ public virtual DbSet historico { get; set; }
+
+ public virtual DbSet items { get; set; }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ modelBuilder
+ .UseCollation("utf8mb4_0900_ai_ci")
+ .HasCharSet("utf8mb4");
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.id).HasName("PRIMARY");
+
+ entity.Property(e => e.creacion)
+ .HasDefaultValueSql("CURRENT_TIMESTAMP")
+ .HasColumnType("datetime");
+ entity.Property(e => e.description).HasMaxLength(1024);
+ entity.Property(e => e.generator).HasMaxLength(128);
+ entity.Property(e => e.language).HasMaxLength(8);
+ entity.Property(e => e.lastBuildDate).HasColumnType("datetime");
+ entity.Property(e => e.link).HasMaxLength(4096);
+ entity.Property(e => e.modificacion)
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("datetime");
+ entity.Property(e => e.title).HasMaxLength(128);
+ });
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.id).HasName("PRIMARY");
+
+ entity.HasIndex(e => e.codigo, "index_codigo").IsUnique();
+
+ entity.Property(e => e.codigo)
+ .HasMaxLength(128)
+ .HasDefaultValueSql("''");
+ entity.Property(e => e.grupo).HasMaxLength(128);
+ entity.Property(e => e.valor)
+ .HasMaxLength(1024)
+ .HasDefaultValueSql("''");
+ });
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.id).HasName("PRIMARY");
+
+ entity.HasIndex(e => e.id_channel, "historico_fk_id_channel");
+
+ entity.HasIndex(e => e.id_item, "historico_fk_id_item");
+
+ entity.Property(e => e.fechaHora)
+ .HasDefaultValueSql("CURRENT_TIMESTAMP")
+ .HasColumnType("datetime");
+ });
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.id).HasName("PRIMARY");
+
+ entity.HasIndex(e => e.id_channel, "FK_id_channel");
+
+ entity.Property(e => e.category).HasMaxLength(64);
+ entity.Property(e => e.creacion)
+ .HasDefaultValueSql("CURRENT_TIMESTAMP")
+ .HasColumnType("datetime");
+ entity.Property(e => e.guid).HasMaxLength(4096);
+ entity.Property(e => e.link).HasMaxLength(4096);
+ entity.Property(e => e.modificacion)
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("datetime");
+ entity.Property(e => e.pubDate).HasColumnType("datetime");
+ entity.Property(e => e.title).HasMaxLength(1024);
+
+ entity.HasOne(d => d.id_channelNavigation).WithMany(p => p.items)
+ .HasForeignKey(d => d.id_channel)
+ .HasConstraintName("FK_id_channel");
+ });
+
+ OnModelCreatingPartial(modelBuilder);
+ }
+
+ partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
+}
diff --git a/bdEmtusa/dbcontext/conexion.cs b/bdEmtusa/dbcontext/conexion.cs
new file mode 100644
index 0000000..f17a8b4
--- /dev/null
+++ b/bdEmtusa/dbcontext/conexion.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using static System.Runtime.InteropServices.JavaScript.JSType;
+using tsUtilidades.Enumeraciones;
+using System.Drawing.Imaging;
+
+namespace bdEmtusa.dbcontext
+{
+ public class Conexion
+ {
+ public string Nombre { get; set; }
+ public string Servidor { get; set; }
+ public int Puerto { get; set; }
+
+ public string Database { get; set; }
+ public string Usuario { get; set; }
+ public string Contraseña { get; set; }
+
+
+ public static List ListaConexiones()
+ {
+ List lc = new List();
+ lc.Add(new Conexion() { Nombre = "Producción", Puerto = 3306, Servidor = "192.168.41.56", Usuario = "root", Contraseña = "0êmF/e#g/*6pZÛLWqölLvPp", Database = "gestionemtusa" });
+ return lc;
+ }
+ internal static string ObtieneConexionDefecto(string NombreConexion="Producción")
+ {
+ try
+ {
+ // server=10.10.10.1;database=Emtusa;port=3306;uid=root;pwd=larga;persistsecurityinfo=True;TreatTinyAsBoolean=False;allowuservariables=True
+ string cs = @";persistsecurityinfo=True;TreatTinyAsBoolean=False;allowuservariables=True";
+ var lc = ListaConexiones();
+
+ var cn = lc.First(x => x.Nombre == NombreConexion);
+ cs = "server=" + cn.Servidor + ";pwd=" + tsUtilidades.crypt.FEncS(cn.Contraseña, @"[JO1]", @"[JD1]", -875421649) + ";port=" + cn.Puerto.ToString() + ";uid=" + cn.Usuario + ";database=" + cn.Database + cs;
+ return cs;
+ }
+ catch (Exception ex)
+ {
+ throw new Exception(ex.Message, ex);
+ }
+ }
+ }
+
+}
diff --git a/bdEmtusa/dbcontext/tscEmtusa.cs b/bdEmtusa/dbcontext/tscEmtusa.cs
new file mode 100644
index 0000000..e76ee97
--- /dev/null
+++ b/bdEmtusa/dbcontext/tscEmtusa.cs
@@ -0,0 +1,144 @@
+//using bdEmtusa.CompiledModels;
+using bdEmtusa.db;
+using bdEmtusa.dbcontext;
+
+using Microsoft.AspNetCore.Mvc.Formatters;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+using System.ComponentModel.DataAnnotations;
+using System.Diagnostics;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
+using tsEFCore8.Extensiones;
+using tsUtilidades;
+using tsUtilidades.Enumeraciones;
+using tsUtilidades.Extensiones;
+using static System.Net.Mime.MediaTypeNames;
+
+namespace bdEmtusa
+{
+ public class tscEmtusa : bdEmtusa.dbcontext.EmtusaContext, tsUtilidades.ItsContexto
+
+ {
+
+ public static bool Cargado = false;
+ private static String? _Ip = null;
+ public string? ip
+ {
+ get
+ {
+ return _Ip;
+ }
+ set
+ {
+ _Ip = value;
+ }
+ }
+
+ public string Aplicaciones { get; private set; }
+
+ public static readonly Microsoft.Extensions.Logging.LoggerFactory _myLoggerFactory =
+ new LoggerFactory(new[] {
+ new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider()
+ });
+
+ private static string? ConexionPorDefecto = null;
+ public static tscEmtusa NuevoContexto(string NombreConexion = "", bool Lazy = true, bool SoloLectura = false, bool ConEventoSavingChanges = true, string aplicaciones = "")
+ {
+
+
+
+ string? cnx = null;
+ if (NombreConexion == "")
+ {
+ if (ConexionPorDefecto == null) ConexionPorDefecto = Conexion.ObtieneConexionDefecto();
+ cnx = ConexionPorDefecto;
+ }
+ else
+ {
+ cnx = Conexion.ObtieneConexionDefecto(NombreConexion);
+ }
+
+ var ob = new DbContextOptionsBuilder();
+ // ob.UseLoggerFactory(_myLoggerFactory);
+ // ob.UseInternalServiceProvider()
+ ob.UseMySql(cnx, Microsoft.EntityFrameworkCore.ServerVersion.Parse("8.0.0-mysql"));
+ if (Lazy) ob.UseLazyLoadingProxies();
+ if (SoloLectura) ob.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
+ var Opciones = ob.Options;
+ tscEmtusa bd = new tscEmtusa(Opciones);
+ bd.Aplicaciones = aplicaciones;
+ if (ConEventoSavingChanges) bd.SavingChanges += GuardandoCambios;
+ return bd;
+
+ }
+
+ private static void CambiosGuardados(object? sender, SavedChangesEventArgs e)
+ {
+
+ }
+
+ //public static Datos.BBDD ObtieneBBDD(string NombreConexion)
+
+ private static void GuardandoCambios(object? sender, SavingChangesEventArgs e)
+ {
+
+
+ }
+
+ public tscEmtusa(DbContextOptions Opciones) : base(Opciones)
+ {
+ if (_Ip == null) { ip = tsEFCore8.bbdd.ObtieneIPMysql(this); }
+ else { ip = _Ip; }
+ }
+
+
+
+ public void AñadeObjeto(object Registro)
+ {
+ this.Add(Registro);
+ }
+
+ public bool CompruebaUnico(EstadosAplicacion estado, string NombreCampo, object Valor, string NombreTablaBase, object DataContext)
+ {
+ return this.CompruebaRegistroUnico(estado == EstadosAplicacion.ModificandoRegistro, "bdEmtusa.db", NombreTablaBase, NombreCampo, Valor, DataContext);
+ }
+ public void EliminaObjeto(object Registro)
+ {
+ if (this.Entry(Registro).State == Microsoft.EntityFrameworkCore.EntityState.Detached)
+ {
+ this.Entry(Registro).State = Microsoft.EntityFrameworkCore.EntityState.Unchanged;
+ }
+ else if (this.Entry(Registro).State == Microsoft.EntityFrameworkCore.EntityState.Added)
+ {
+ this.Remove(Registro);
+ this.Entry(Registro).State = Microsoft.EntityFrameworkCore.EntityState.Unchanged;
+ }
+ else
+ {
+ this.Remove(Registro);
+ }
+
+ }
+
+ public int GuardarCambios()
+ {
+ return this.SaveChanges();
+ }
+
+ public bool HayModificaciones()
+ {
+ return this.ChangeTracker.HasChanges();
+ }
+ public int ObtieneLongitudCampo(string NombreTablaBase, string NombreCampo)
+ {
+ return this.ObtieneMaximaLongitudCampo("bdEmtusa.db", NombreTablaBase, NombreCampo);
+ }
+ }
+}
\ No newline at end of file
diff --git a/bdEmtusa/efpt.config.json b/bdEmtusa/efpt.config.json
new file mode 100644
index 0000000..3d66fc1
--- /dev/null
+++ b/bdEmtusa/efpt.config.json
@@ -0,0 +1,66 @@
+{
+ "CodeGenerationMode": 4,
+ "ContextClassName": "EmtusaContext",
+ "ContextNamespace": null,
+ "FilterSchemas": false,
+ "IncludeConnectionString": false,
+ "IrregularWords": null,
+ "MinimumProductVersion": "2.6.1382",
+ "ModelNamespace": null,
+ "OutputContextPath": "dbcontext",
+ "OutputPath": "db",
+ "PluralRules": null,
+ "PreserveCasingWithRegex": true,
+ "ProjectRootNamespace": "bdEmtusa",
+ "Schemas": null,
+ "SelectedHandlebarsLanguage": 2,
+ "SelectedToBeGenerated": 0,
+ "SingularRules": null,
+ "T4TemplatePath": null,
+ "Tables": [
+ {
+ "Name": "channels",
+ "ObjectType": 0
+ },
+ {
+ "Name": "configuracion",
+ "ObjectType": 0
+ },
+ {
+ "Name": "historico",
+ "ObjectType": 0
+ },
+ {
+ "Name": "items",
+ "ObjectType": 0
+ }
+ ],
+ "UiHint": null,
+ "UncountableWords": null,
+ "UseAsyncStoredProcedureCalls": true,
+ "UseBoolPropertiesWithoutDefaultSql": true,
+ "UseDatabaseNames": true,
+ "UseDatabaseNamesForRoutines": true,
+ "UseDateOnlyTimeOnly": false,
+ "UseDbContextSplitting": false,
+ "UseDecimalDataAnnotationForSprocResult": true,
+ "UseFluentApiOnly": true,
+ "UseHandleBars": false,
+ "UseHierarchyId": false,
+ "UseInflector": false,
+ "UseInternalAccessModifiersForSprocsAndFunctions": false,
+ "UseLegacyPluralizer": false,
+ "UseManyToManyEntity": false,
+ "UseNoDefaultConstructor": false,
+ "UseNoNavigations": false,
+ "UseNoObjectFilter": false,
+ "UseNodaTime": false,
+ "UseNullableReferences": true,
+ "UsePrefixNavigationNaming": false,
+ "UseSchemaFolders": false,
+ "UseSchemaNamespaces": false,
+ "UseSpatial": false,
+ "UseT4": true,
+ "UseT4Split": false,
+ "UseTypedTvpParameters": true
+}
\ No newline at end of file
diff --git a/swEmtusa/Controllers/AuthController.cs b/swEmtusa/Controllers/AuthController.cs
new file mode 100644
index 0000000..6623963
--- /dev/null
+++ b/swEmtusa/Controllers/AuthController.cs
@@ -0,0 +1,128 @@
+using bdCOAS.db;
+using Microsoft.AspNetCore.Mvc;
+using SwaggerAutenticacion.Clases;
+using System.Linq.Dynamic.Core;
+using tsUtilidades;
+using System.Security.Claims;
+
+
+namespace SwaggerAutenticacion.Controllers
+{
+ [ApiController]
+ [Route("[controller]")]
+ public class AuthController : Controller
+ {
+
+ private readonly IConfiguration jwtSettings;
+
+ public AuthController(IConfiguration configuration)
+ {
+
+ jwtSettings = configuration.GetSection("Jwt");
+ }
+
+ [HttpPost("ComprobarUser")]
+ public ActionResult PostComprobarUser([FromBody] DatosAuth model)
+ {
+ var bd = bdCOAS.tsCOAS.NuevoContextoDirecto();
+
+
+
+
+ try
+ {
+ autorizacionesexternas externo = bd.autorizacionesexternas.FirstOrDefault(x => x.Codigo == model.nombreExterno);
+
+ //var externo = bd.autorizacionesexternas.FirstOrDefault(x => x.Nombre == model.nombreExterno);
+
+ if (externo != null)
+ {
+ var pwEmpresaEncrypt = tsUtilidades.crypt.SHA1("M3Soft." + model.pwExterno);
+
+ if (pwEmpresaEncrypt != externo.HashPassword) throw new Exception("PassWord Incorrecta");
+ }
+ else
+ {
+ throw new Exception("Autorización no encontrada.");
+ }
+
+
+ var token = "";
+ try
+ {
+ var sContraseñaenc = tsUtilidades.crypt.SHA1("M3Soft." + model.pwColegiado);
+ Exception ex = null;
+ accesoswebcoas nac = null;
+ var col = bd.Colegiados.First(x => x.NumeroColegiado == model.identificacionColegiado || x.NIF == model.identificacionColegiado);
+ clavesacceso.LoginCoas(bd, col.NumeroColegiado, sContraseñaenc, "", clavesacceso.TipoLoginEnum.EXTERNOS_1, ref ex, ref nac);
+ if (ex != null) throw ex;
+
+ externo.FechaUltimaConexion = DateTime.Now;
+ bd.Update(externo);
+ bd.SaveChanges();
+
+ token = AuthHandler.GenerateJwtToken(jwtSettings, col.idColegiado.ToString());
+ return Ok(new { token });
+ }
+ catch (tsExcepcion e)
+ {
+ return Unauthorized("Credenciales Colegiado no válidas. " + e.Message);
+ }
+ catch (Exception e)
+ {
+ return BadRequest($"Ha ocurrido un error. Mensaje de error: {e.Message}");
+ }
+ }
+ catch (Exception e)
+ {
+ return Unauthorized("Credenciales Empresa no válidas. " + e.Message);
+ }
+ }
+
+
+ [HttpPost("LoginExterno")]
+ public ActionResult