Tipologia cliente

This commit is contained in:
2025-12-15 11:01:14 +01:00
parent 69d28744f6
commit 664cee9656
22 changed files with 1118 additions and 491 deletions

View File

@ -23,26 +23,12 @@ public class Cliente : EntitaBase
public List<Destinazione> Destinazioni { get; set; } public List<Destinazione> Destinazioni { get; set; }
public string? Rid { get; set; } public string? Rid { get; set; }
public ClienteTipo TipologiaCliente { get; set; } [ForeignKey(nameof(TipologiaCliente))]
public Guid? TipologiaClienteId { get; set; }
public TipologiaCliente TipologiaCliente { get; set; }
public ClienteStato StatoCliente { get; set; } public ClienteStato StatoCliente { get; set; }
} }
public enum ClienteTipo
{
[Description("Alberghiero")]
Alberghiero = 0,
[Description("Ristoranti")]
Ristoranti = 1,
[Description("Pizzerie")]
Pizzerie = 2,
[Description("Wine Bar")]
WineBar = 3,
[Description("Bar")]
Bar = 4,
[Description("Ristorazione Collettiva")]
RistorazioneCollettiva = 5
}
public enum ClienteStato public enum ClienteStato
{ {
[Description("Cliente")] [Description("Cliente")]

View File

@ -23,7 +23,6 @@ public class IscrizioneEvento : EntitaBase
public Destinazione Destinazione { get; set; } public Destinazione Destinazione { get; set; }
public int Partecipanti{ get; set; } public int Partecipanti{ get; set; }
public string Note{ get; set; } public string Note{ get; set; }
public string QrCodeCode{ get; set; }
public bool ScanCompleto{ get; set; } public bool ScanCompleto{ get; set; }
public DateTime? DataScan{ get; set; } public DateTime? DataScan{ get; set; }
public string? Nome{ get; set; } public string? Nome{ get; set; }
@ -34,7 +33,9 @@ public class IscrizioneEvento : EntitaBase
public string? Comune { get; set; } public string? Comune { get; set; }
public string? Cap { get; set; } public string? Cap { get; set; }
public string? RagioneSociale { get; set; } public string? RagioneSociale { get; set; }
public ClienteTipo Tipologia { get; set; } [ForeignKey(nameof(TipologiaCliente))]
public Guid? TipologiaClienteId { get; set; }
public TipologiaCliente TipologiaCliente { get; set; }
public string? EsperienzaConDAC { get; set; } public string? EsperienzaConDAC { get; set; }
public RuoloTipo Ruolo { get; set; } public RuoloTipo Ruolo { get; set; }
} }

View File

@ -0,0 +1,8 @@
using StandManager.Domain.Entita.Base;
namespace StandManager.Domain.Entita;
public class TipologiaCliente : EntitaBase
{
public string Nome { get; set; }
}

View File

@ -17,6 +17,7 @@ public class StandManagerDbContext : OAServiceContext
public DbSet<InvitoEvento> InvitoEvento { get; set; } public DbSet<InvitoEvento> InvitoEvento { get; set; }
public DbSet<IscrizioneEvento> IscrizioneEvento { get; set; } public DbSet<IscrizioneEvento> IscrizioneEvento { get; set; }
public DbSet<Referente> Referente { get; set; } public DbSet<Referente> Referente { get; set; }
public DbSet<TipologiaCliente> TipologiaCliente { get; set; }
public DbSet<Utente> Utente { get; set; } public DbSet<Utente> Utente { get; set; }

View File

@ -0,0 +1,717 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using StandManager.Infrastructure.DAL.Context;
#nullable disable
namespace StandManager.Infrastructure.Migrations
{
[DbContext(typeof(StandManagerDbContext))]
[Migration("20251215095446_TipoCliente")]
partial class TipoCliente
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.11")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("StandManager.Domain.Entita.Cliente", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("AgenteId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Cap")
.HasColumnType("nvarchar(max)");
b.Property<string>("Citta")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("DataCreazione")
.HasColumnType("datetime2");
b.Property<DateTime?>("DataModifica")
.HasColumnType("datetime2");
b.Property<bool>("Eliminato")
.HasColumnType("bit");
b.Property<string>("Email")
.HasColumnType("nvarchar(max)");
b.Property<string>("EmailInvito")
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("IdUtenteCreazione")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("IdUtenteModifica")
.HasColumnType("uniqueidentifier");
b.Property<string>("Indirizzo")
.HasColumnType("nvarchar(max)");
b.Property<string>("NumeroTelefono")
.HasColumnType("nvarchar(max)");
b.Property<string>("PartitaIva")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("RagioneSociale")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Rid")
.HasColumnType("nvarchar(max)");
b.Property<int>("StatoCliente")
.HasColumnType("int");
b.Property<Guid?>("TipologiaClienteId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("AgenteId");
b.HasIndex("IdUtenteCreazione");
b.HasIndex("IdUtenteModifica");
b.HasIndex("TipologiaClienteId");
b.ToTable("Cliente");
});
modelBuilder.Entity("StandManager.Domain.Entita.Destinazione", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("AgenteId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Cap")
.HasColumnType("nvarchar(max)");
b.Property<string>("Citta")
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("ClienteId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("DataCreazione")
.HasColumnType("datetime2");
b.Property<DateTime?>("DataModifica")
.HasColumnType("datetime2");
b.Property<bool>("Eliminato")
.HasColumnType("bit");
b.Property<string>("Email")
.HasColumnType("nvarchar(max)");
b.Property<string>("EmailInvito")
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("IdUtenteCreazione")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("IdUtenteModifica")
.HasColumnType("uniqueidentifier");
b.Property<string>("Indirizzo")
.HasColumnType("nvarchar(max)");
b.Property<string>("NumeroTelefono")
.HasColumnType("nvarchar(max)");
b.Property<string>("PartitaIva")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("RagioneSociale")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("AgenteId");
b.HasIndex("ClienteId");
b.HasIndex("IdUtenteCreazione");
b.HasIndex("IdUtenteModifica");
b.ToTable("Destinazione");
});
modelBuilder.Entity("StandManager.Domain.Entita.Evento", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("DataA")
.HasColumnType("datetime2");
b.Property<DateTime>("DataCreazione")
.HasColumnType("datetime2");
b.Property<DateTime>("DataDa")
.HasColumnType("datetime2");
b.Property<DateTime?>("DataModifica")
.HasColumnType("datetime2");
b.Property<string>("Descrizione")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("Eliminato")
.HasColumnType("bit");
b.Property<Guid?>("IdUtenteCreazione")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("IdUtenteModifica")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("IscrizioneA")
.HasColumnType("datetime2");
b.Property<DateTime>("IscrizioneDa")
.HasColumnType("datetime2");
b.Property<string>("Luogo")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("TemplateHtmlMailInvito")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("TemplateHtmlMailIscrizione")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Titolo")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("IdUtenteCreazione");
b.HasIndex("IdUtenteModifica");
b.ToTable("Evento");
});
modelBuilder.Entity("StandManager.Domain.Entita.InvitoEvento", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("ClienteId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("DataCreazione")
.HasColumnType("datetime2");
b.Property<DateTime?>("DataModifica")
.HasColumnType("datetime2");
b.Property<bool>("Eliminato")
.HasColumnType("bit");
b.Property<Guid?>("EventoId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("IdUtenteCreazione")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("IdUtenteModifica")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("ClienteId");
b.HasIndex("EventoId");
b.HasIndex("IdUtenteCreazione");
b.HasIndex("IdUtenteModifica");
b.ToTable("InvitoEvento");
});
modelBuilder.Entity("StandManager.Domain.Entita.IscrizioneEvento", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Cap")
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("ClienteId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Cognome")
.HasColumnType("nvarchar(max)");
b.Property<string>("Comune")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("DataCreazione")
.HasColumnType("datetime2");
b.Property<DateTime?>("DataModifica")
.HasColumnType("datetime2");
b.Property<DateTime?>("DataScan")
.HasColumnType("datetime2");
b.Property<Guid?>("DestinazioneId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("Eliminato")
.HasColumnType("bit");
b.Property<string>("Email")
.HasColumnType("nvarchar(max)");
b.Property<string>("EsperienzaConDAC")
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("EventoId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("IdUtenteCreazione")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("IdUtenteModifica")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("InvitoEventoId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Nome")
.HasColumnType("nvarchar(max)");
b.Property<string>("Note")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("NumeroTelefono")
.HasColumnType("nvarchar(max)");
b.Property<int>("Partecipanti")
.HasColumnType("int");
b.Property<string>("Provincia")
.HasColumnType("nvarchar(max)");
b.Property<string>("RagioneSociale")
.HasColumnType("nvarchar(max)");
b.Property<int>("Ruolo")
.HasColumnType("int");
b.Property<bool>("ScanCompleto")
.HasColumnType("bit");
b.Property<Guid?>("TipologiaClienteId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("ClienteId");
b.HasIndex("DestinazioneId");
b.HasIndex("EventoId");
b.HasIndex("IdUtenteCreazione");
b.HasIndex("IdUtenteModifica");
b.HasIndex("InvitoEventoId");
b.HasIndex("TipologiaClienteId");
b.ToTable("IscrizioneEvento");
});
modelBuilder.Entity("StandManager.Domain.Entita.Referente", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Cognome")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("DataCreazione")
.HasColumnType("datetime2");
b.Property<DateTime?>("DataModifica")
.HasColumnType("datetime2");
b.Property<Guid?>("DestinazioneId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("Eliminato")
.HasColumnType("bit");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("IdUtenteCreazione")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("IdUtenteModifica")
.HasColumnType("uniqueidentifier");
b.Property<string>("Nome")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("NumeroTelefono")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Ruolo")
.HasColumnType("int");
b.Property<string>("RuoloNote")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("DestinazioneId");
b.HasIndex("IdUtenteCreazione");
b.HasIndex("IdUtenteModifica");
b.ToTable("Referente");
});
modelBuilder.Entity("StandManager.Domain.Entita.TipologiaCliente", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("DataCreazione")
.HasColumnType("datetime2");
b.Property<DateTime?>("DataModifica")
.HasColumnType("datetime2");
b.Property<bool>("Eliminato")
.HasColumnType("bit");
b.Property<Guid?>("IdUtenteCreazione")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("IdUtenteModifica")
.HasColumnType("uniqueidentifier");
b.Property<string>("Nome")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("IdUtenteCreazione");
b.HasIndex("IdUtenteModifica");
b.ToTable("TipologiaCliente");
});
modelBuilder.Entity("StandManager.Domain.Entita.Utente", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Cognome")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("DataCreazione")
.HasColumnType("datetime2");
b.Property<DateTime?>("DataModifica")
.HasColumnType("datetime2");
b.Property<bool>("Eliminato")
.HasColumnType("bit");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("IdUtenteCreazione")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("IdUtenteModifica")
.HasColumnType("uniqueidentifier");
b.Property<string>("Nome")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("IdUtenteCreazione");
b.HasIndex("IdUtenteModifica");
b.ToTable("Utente");
});
modelBuilder.Entity("StandManager.Domain.Entita.Cliente", b =>
{
b.HasOne("StandManager.Domain.Entita.Utente", "Agente")
.WithMany()
.HasForeignKey("AgenteId");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione")
.WithMany()
.HasForeignKey("IdUtenteCreazione");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteModifica")
.WithMany()
.HasForeignKey("IdUtenteModifica");
b.HasOne("StandManager.Domain.Entita.TipologiaCliente", "TipologiaCliente")
.WithMany()
.HasForeignKey("TipologiaClienteId");
b.Navigation("Agente");
b.Navigation("TipologiaCliente");
b.Navigation("UtenteCreazione");
b.Navigation("UtenteModifica");
});
modelBuilder.Entity("StandManager.Domain.Entita.Destinazione", b =>
{
b.HasOne("StandManager.Domain.Entita.Utente", "Agente")
.WithMany()
.HasForeignKey("AgenteId");
b.HasOne("StandManager.Domain.Entita.Cliente", "Cliente")
.WithMany("Destinazioni")
.HasForeignKey("ClienteId");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione")
.WithMany()
.HasForeignKey("IdUtenteCreazione");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteModifica")
.WithMany()
.HasForeignKey("IdUtenteModifica");
b.Navigation("Agente");
b.Navigation("Cliente");
b.Navigation("UtenteCreazione");
b.Navigation("UtenteModifica");
});
modelBuilder.Entity("StandManager.Domain.Entita.Evento", b =>
{
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione")
.WithMany()
.HasForeignKey("IdUtenteCreazione");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteModifica")
.WithMany()
.HasForeignKey("IdUtenteModifica");
b.Navigation("UtenteCreazione");
b.Navigation("UtenteModifica");
});
modelBuilder.Entity("StandManager.Domain.Entita.InvitoEvento", b =>
{
b.HasOne("StandManager.Domain.Entita.Cliente", "Cliente")
.WithMany()
.HasForeignKey("ClienteId");
b.HasOne("StandManager.Domain.Entita.Evento", "Evento")
.WithMany()
.HasForeignKey("EventoId");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione")
.WithMany()
.HasForeignKey("IdUtenteCreazione");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteModifica")
.WithMany()
.HasForeignKey("IdUtenteModifica");
b.Navigation("Cliente");
b.Navigation("Evento");
b.Navigation("UtenteCreazione");
b.Navigation("UtenteModifica");
});
modelBuilder.Entity("StandManager.Domain.Entita.IscrizioneEvento", b =>
{
b.HasOne("StandManager.Domain.Entita.Cliente", "Cliente")
.WithMany()
.HasForeignKey("ClienteId");
b.HasOne("StandManager.Domain.Entita.Destinazione", "Destinazione")
.WithMany()
.HasForeignKey("DestinazioneId");
b.HasOne("StandManager.Domain.Entita.Evento", "Evento")
.WithMany()
.HasForeignKey("EventoId");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione")
.WithMany()
.HasForeignKey("IdUtenteCreazione");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteModifica")
.WithMany()
.HasForeignKey("IdUtenteModifica");
b.HasOne("StandManager.Domain.Entita.InvitoEvento", "InvitoEvento")
.WithMany("IscrizioniEvento")
.HasForeignKey("InvitoEventoId");
b.HasOne("StandManager.Domain.Entita.TipologiaCliente", "TipologiaCliente")
.WithMany()
.HasForeignKey("TipologiaClienteId");
b.Navigation("Cliente");
b.Navigation("Destinazione");
b.Navigation("Evento");
b.Navigation("InvitoEvento");
b.Navigation("TipologiaCliente");
b.Navigation("UtenteCreazione");
b.Navigation("UtenteModifica");
});
modelBuilder.Entity("StandManager.Domain.Entita.Referente", b =>
{
b.HasOne("StandManager.Domain.Entita.Destinazione", "Destinazione")
.WithMany("Referenti")
.HasForeignKey("DestinazioneId");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione")
.WithMany()
.HasForeignKey("IdUtenteCreazione");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteModifica")
.WithMany()
.HasForeignKey("IdUtenteModifica");
b.Navigation("Destinazione");
b.Navigation("UtenteCreazione");
b.Navigation("UtenteModifica");
});
modelBuilder.Entity("StandManager.Domain.Entita.TipologiaCliente", b =>
{
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione")
.WithMany()
.HasForeignKey("IdUtenteCreazione");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteModifica")
.WithMany()
.HasForeignKey("IdUtenteModifica");
b.Navigation("UtenteCreazione");
b.Navigation("UtenteModifica");
});
modelBuilder.Entity("StandManager.Domain.Entita.Utente", b =>
{
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione")
.WithMany()
.HasForeignKey("IdUtenteCreazione");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteModifica")
.WithMany()
.HasForeignKey("IdUtenteModifica");
b.Navigation("UtenteCreazione");
b.Navigation("UtenteModifica");
});
modelBuilder.Entity("StandManager.Domain.Entita.Cliente", b =>
{
b.Navigation("Destinazioni");
});
modelBuilder.Entity("StandManager.Domain.Entita.Destinazione", b =>
{
b.Navigation("Referenti");
});
modelBuilder.Entity("StandManager.Domain.Entita.InvitoEvento", b =>
{
b.Navigation("IscrizioniEvento");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,152 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace StandManager.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class TipoCliente : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "QrCodeCode",
table: "IscrizioneEvento");
migrationBuilder.DropColumn(
name: "Tipologia",
table: "IscrizioneEvento");
migrationBuilder.DropColumn(
name: "TipologiaCliente",
table: "Cliente");
migrationBuilder.AddColumn<Guid>(
name: "TipologiaClienteId",
table: "IscrizioneEvento",
type: "uniqueidentifier",
nullable: true);
migrationBuilder.AddColumn<Guid>(
name: "TipologiaClienteId",
table: "Cliente",
type: "uniqueidentifier",
nullable: true);
migrationBuilder.CreateTable(
name: "TipologiaCliente",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Nome = table.Column<string>(type: "nvarchar(max)", nullable: false),
DataCreazione = table.Column<DateTime>(type: "datetime2", nullable: false),
DataModifica = table.Column<DateTime>(type: "datetime2", nullable: true),
Eliminato = table.Column<bool>(type: "bit", nullable: false),
IdUtenteCreazione = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
IdUtenteModifica = table.Column<Guid>(type: "uniqueidentifier", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_TipologiaCliente", x => x.Id);
table.ForeignKey(
name: "FK_TipologiaCliente_Utente_IdUtenteCreazione",
column: x => x.IdUtenteCreazione,
principalTable: "Utente",
principalColumn: "Id");
table.ForeignKey(
name: "FK_TipologiaCliente_Utente_IdUtenteModifica",
column: x => x.IdUtenteModifica,
principalTable: "Utente",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_IscrizioneEvento_TipologiaClienteId",
table: "IscrizioneEvento",
column: "TipologiaClienteId");
migrationBuilder.CreateIndex(
name: "IX_Cliente_TipologiaClienteId",
table: "Cliente",
column: "TipologiaClienteId");
migrationBuilder.CreateIndex(
name: "IX_TipologiaCliente_IdUtenteCreazione",
table: "TipologiaCliente",
column: "IdUtenteCreazione");
migrationBuilder.CreateIndex(
name: "IX_TipologiaCliente_IdUtenteModifica",
table: "TipologiaCliente",
column: "IdUtenteModifica");
migrationBuilder.AddForeignKey(
name: "FK_Cliente_TipologiaCliente_TipologiaClienteId",
table: "Cliente",
column: "TipologiaClienteId",
principalTable: "TipologiaCliente",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_IscrizioneEvento_TipologiaCliente_TipologiaClienteId",
table: "IscrizioneEvento",
column: "TipologiaClienteId",
principalTable: "TipologiaCliente",
principalColumn: "Id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Cliente_TipologiaCliente_TipologiaClienteId",
table: "Cliente");
migrationBuilder.DropForeignKey(
name: "FK_IscrizioneEvento_TipologiaCliente_TipologiaClienteId",
table: "IscrizioneEvento");
migrationBuilder.DropTable(
name: "TipologiaCliente");
migrationBuilder.DropIndex(
name: "IX_IscrizioneEvento_TipologiaClienteId",
table: "IscrizioneEvento");
migrationBuilder.DropIndex(
name: "IX_Cliente_TipologiaClienteId",
table: "Cliente");
migrationBuilder.DropColumn(
name: "TipologiaClienteId",
table: "IscrizioneEvento");
migrationBuilder.DropColumn(
name: "TipologiaClienteId",
table: "Cliente");
migrationBuilder.AddColumn<string>(
name: "QrCodeCode",
table: "IscrizioneEvento",
type: "nvarchar(max)",
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<int>(
name: "Tipologia",
table: "IscrizioneEvento",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "TipologiaCliente",
table: "Cliente",
type: "int",
nullable: false,
defaultValue: 0);
}
}
}

View File

@ -78,8 +78,8 @@ namespace StandManager.Infrastructure.Migrations
b.Property<int>("StatoCliente") b.Property<int>("StatoCliente")
.HasColumnType("int"); .HasColumnType("int");
b.Property<int>("TipologiaCliente") b.Property<Guid?>("TipologiaClienteId")
.HasColumnType("int"); .HasColumnType("uniqueidentifier");
b.HasKey("Id"); b.HasKey("Id");
@ -89,6 +89,8 @@ namespace StandManager.Infrastructure.Migrations
b.HasIndex("IdUtenteModifica"); b.HasIndex("IdUtenteModifica");
b.HasIndex("TipologiaClienteId");
b.ToTable("Cliente"); b.ToTable("Cliente");
}); });
@ -327,10 +329,6 @@ namespace StandManager.Infrastructure.Migrations
b.Property<string>("Provincia") b.Property<string>("Provincia")
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<string>("QrCodeCode")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("RagioneSociale") b.Property<string>("RagioneSociale")
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
@ -340,8 +338,8 @@ namespace StandManager.Infrastructure.Migrations
b.Property<bool>("ScanCompleto") b.Property<bool>("ScanCompleto")
.HasColumnType("bit"); .HasColumnType("bit");
b.Property<int>("Tipologia") b.Property<Guid?>("TipologiaClienteId")
.HasColumnType("int"); .HasColumnType("uniqueidentifier");
b.HasKey("Id"); b.HasKey("Id");
@ -357,6 +355,8 @@ namespace StandManager.Infrastructure.Migrations
b.HasIndex("InvitoEventoId"); b.HasIndex("InvitoEventoId");
b.HasIndex("TipologiaClienteId");
b.ToTable("IscrizioneEvento"); b.ToTable("IscrizioneEvento");
}); });
@ -418,6 +418,40 @@ namespace StandManager.Infrastructure.Migrations
b.ToTable("Referente"); b.ToTable("Referente");
}); });
modelBuilder.Entity("StandManager.Domain.Entita.TipologiaCliente", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("DataCreazione")
.HasColumnType("datetime2");
b.Property<DateTime?>("DataModifica")
.HasColumnType("datetime2");
b.Property<bool>("Eliminato")
.HasColumnType("bit");
b.Property<Guid?>("IdUtenteCreazione")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("IdUtenteModifica")
.HasColumnType("uniqueidentifier");
b.Property<string>("Nome")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("IdUtenteCreazione");
b.HasIndex("IdUtenteModifica");
b.ToTable("TipologiaCliente");
});
modelBuilder.Entity("StandManager.Domain.Entita.Utente", b => modelBuilder.Entity("StandManager.Domain.Entita.Utente", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")
@ -482,8 +516,14 @@ namespace StandManager.Infrastructure.Migrations
.WithMany() .WithMany()
.HasForeignKey("IdUtenteModifica"); .HasForeignKey("IdUtenteModifica");
b.HasOne("StandManager.Domain.Entita.TipologiaCliente", "TipologiaCliente")
.WithMany()
.HasForeignKey("TipologiaClienteId");
b.Navigation("Agente"); b.Navigation("Agente");
b.Navigation("TipologiaCliente");
b.Navigation("UtenteCreazione"); b.Navigation("UtenteCreazione");
b.Navigation("UtenteModifica"); b.Navigation("UtenteModifica");
@ -584,6 +624,10 @@ namespace StandManager.Infrastructure.Migrations
.WithMany("IscrizioniEvento") .WithMany("IscrizioniEvento")
.HasForeignKey("InvitoEventoId"); .HasForeignKey("InvitoEventoId");
b.HasOne("StandManager.Domain.Entita.TipologiaCliente", "TipologiaCliente")
.WithMany()
.HasForeignKey("TipologiaClienteId");
b.Navigation("Cliente"); b.Navigation("Cliente");
b.Navigation("Destinazione"); b.Navigation("Destinazione");
@ -592,6 +636,8 @@ namespace StandManager.Infrastructure.Migrations
b.Navigation("InvitoEvento"); b.Navigation("InvitoEvento");
b.Navigation("TipologiaCliente");
b.Navigation("UtenteCreazione"); b.Navigation("UtenteCreazione");
b.Navigation("UtenteModifica"); b.Navigation("UtenteModifica");
@ -618,6 +664,21 @@ namespace StandManager.Infrastructure.Migrations
b.Navigation("UtenteModifica"); b.Navigation("UtenteModifica");
}); });
modelBuilder.Entity("StandManager.Domain.Entita.TipologiaCliente", b =>
{
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione")
.WithMany()
.HasForeignKey("IdUtenteCreazione");
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteModifica")
.WithMany()
.HasForeignKey("IdUtenteModifica");
b.Navigation("UtenteCreazione");
b.Navigation("UtenteModifica");
});
modelBuilder.Entity("StandManager.Domain.Entita.Utente", b => modelBuilder.Entity("StandManager.Domain.Entita.Utente", b =>
{ {
b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione") b.HasOne("StandManager.Domain.Entita.Utente", "UtenteCreazione")

View File

@ -8,6 +8,7 @@
public IInvitoEventoService InvitoEventoService{ get; set; } public IInvitoEventoService InvitoEventoService{ get; set; }
public IIscrizioneEventoService IscrizioneEventoService{ get; set; } public IIscrizioneEventoService IscrizioneEventoService{ get; set; }
public IReferenteService ReferenteService{ get; set; } public IReferenteService ReferenteService{ get; set; }
public ITipologiaClienteService TipologiaClienteService { get; set; }
public IUtenteService UtenteService { get; set; } public IUtenteService UtenteService { get; set; }
} }
} }

View File

@ -0,0 +1,6 @@
using OAService.Service.Servizi.Interfacce;
using StandManager.Domain.Entita;
namespace StandManager.Service.Interfaces;
public interface ITipologiaClienteService : ITService<TipologiaCliente> {}

View File

@ -5,7 +5,8 @@ namespace StandManager.Service;
public class ManagerService : IManagerService public class ManagerService : IManagerService
{ {
public ManagerService(IUtenteService utenteService, IClienteService clienteService, IDestinazioneService destinazioneService, IEventoService eventoService, public ManagerService(IUtenteService utenteService, IClienteService clienteService, IDestinazioneService destinazioneService, IEventoService eventoService,
IInvitoEventoService invitoEventoService, IIscrizioneEventoService iscrizioneEventoService, IReferenteService referenteService) IInvitoEventoService invitoEventoService, IIscrizioneEventoService iscrizioneEventoService, IReferenteService referenteService,
ITipologiaClienteService tipologiaClienteService)
{ {
UtenteService = utenteService; UtenteService = utenteService;
ClienteService = clienteService; ClienteService = clienteService;
@ -14,6 +15,7 @@ public class ManagerService : IManagerService
InvitoEventoService = invitoEventoService; InvitoEventoService = invitoEventoService;
IscrizioneEventoService = iscrizioneEventoService; IscrizioneEventoService = iscrizioneEventoService;
ReferenteService = referenteService; ReferenteService = referenteService;
TipologiaClienteService = tipologiaClienteService;
} }
public IUtenteService UtenteService { get; set; } public IUtenteService UtenteService { get; set; }
@ -23,4 +25,5 @@ public class ManagerService : IManagerService
public IInvitoEventoService InvitoEventoService{ get; set; } public IInvitoEventoService InvitoEventoService{ get; set; }
public IIscrizioneEventoService IscrizioneEventoService { get; set; } public IIscrizioneEventoService IscrizioneEventoService { get; set; }
public IReferenteService ReferenteService { get; set; } public IReferenteService ReferenteService { get; set; }
public ITipologiaClienteService TipologiaClienteService { get; set; }
} }

View File

@ -0,0 +1,16 @@
using OAService.Service.Servizi.Implementazioni;
using StandManager.Domain.Entita;
using StandManager.Service.Interfaces;
using StandManager.Service.Repository;
namespace StandManager.Service;
public class TipologiaClienteService : TService<TipologiaCliente>, ITipologiaClienteService
{
private readonly IStandManagerUnitOfWork _unitOfWork;
public TipologiaClienteService(IStandManagerUnitOfWork unitOfWork) : base(unitOfWork)
{
_unitOfWork = unitOfWork;
}
}

View File

@ -0,0 +1,24 @@
<footer class="footer bg-red text-white">
<div class="container-xl">
<div class="row align-items-start">
<h3><b>DAC S.p.A.</b></h3>
<div class="col-4 text-left">
C.F. / P. IVA: IT03038290171<br />
Reg. Imp. di città n. 03038290171<br />
R.E.A. n. BS-313463<br />
Capitale Sociale € 3.000.000,00 i.v.<br />
</div>
<div class="col-4 text-left">
<i class="fa-regular fa-map"></i><b> Sede legale e amministrativa</b><br />
Via G.Marconi, n.15 - 25020 Flero (BS)<br />
<i class="fa-solid fa-phone"></i><b> Tel. +39 030 256 8211</b><br />
<i class="fa-regular fa-envelope"></i><b> info@gruppodac.eu</b>
</div>
<div class="col-4 text-center">
<a href="#" class="text-white mx-2 text-decoration-none" aria-label="Button"><i class="fa-brands fa-facebook"></i></a>
<a href="#" class="text-white mx-2 text-decoration-none" aria-label="Button"><i class="fa-brands fa-instagram"></i></a>
<a href="#" class="text-white mx-2 text-decoration-none" aria-label="Button"><i class="fa-brands fa-youtube"></i></a>
</div>
</div>
</div>
</footer>

View File

@ -116,9 +116,9 @@
</div> </div>
<div class="col-6 mb-3"> <div class="col-6 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Tipologia</RadzenText> <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Tipologia</RadzenText>
<RadzenDropDown @bind-Value="@iscrizione.TipologiaInt" TValue="int?" Style="width: 100%" TextProperty="Description" ValueProperty="Key" Placeholder="Seleziona la tipologia" <RadzenDropDown @bind-Value="@iscrizione.TipologiaClienteId" TValue="Guid" Style="width: 100%" TextProperty="Description" ValueProperty="Key" Placeholder="Seleziona la tipologia"
Data="@tipologiaList" Size="ButtonSize.Small" /> Data="@tipologiaList" Size="ButtonSize.Small" />
<ValidationMessage For="@(() => iscrizione.TipologiaInt)" /> <ValidationMessage For="@(() => iscrizione.TipologiaClienteId)" />
</div> </div>
</div> </div>
@ -140,9 +140,9 @@
<div class="row"> <div class="row">
<div class="col-6 mb-3"> <div class="col-6 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Destinazione</RadzenText> <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Destinazione</RadzenText>
<RadzenDropDown @bind-Value="@iscrizione.Destinazione" Style="width: 100%" TextProperty="RagioneSociale" Placeholder="Seleziona la destinazione" <RadzenDropDown @bind-Value="@iscrizione.DestinazioneId" Style="width: 100%" ValueProperty="Id" TextProperty="RagioneSociale" Placeholder="Seleziona la destinazione"
Data="@destinazioniList" Size="ButtonSize.Small" /> Data="@destinazioniList" Size="ButtonSize.Small" />
<ValidationMessage For="@(() => iscrizione.Destinazione)" /> <ValidationMessage For="@(() => iscrizione.DestinazioneId)" />
</div> </div>
<div class="col-6 mb-3"> <div class="col-6 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Numero di partecipanti</RadzenText> <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Numero di partecipanti</RadzenText>
@ -221,31 +221,6 @@
} }
</div> </div>
<footer class="footer bg-red text-white">
<div class="container-xl">
<div class="row align-items-start">
<h3><b>DAC S.p.A.</b></h3>
<div class="col-4 text-left">
C.F. / P. IVA: IT03038290171<br />
Reg. Imp. di città n. 03038290171<br />
R.E.A. n. BS-313463<br />
Capitale Sociale € 3.000.000,00 i.v.<br />
</div>
<div class="col-4 text-left">
<b><i class="fa-regular fa-map"></i> Sede legale e amministrativa</b><br />
Via G.Marconi, n.15 - 25020 Flero (BS)<br />
<b><i class="fa-solid fa-phone"></i> Tel. +39 030 256 8211</b><br />
<b><i class="fa-regular fa-envelope"></i> info@gruppodac.eu</b>
</div>
<div class="col-4 text-center">
<a href="#" class="text-white mx-2 text-decoration-none" aria-label="Button"><i class="fa-brands fa-facebook"></i></a>
<a href="#" class="text-white mx-2 text-decoration-none" aria-label="Button"><i class="fa-brands fa-instagram"></i></a>
<a href="#" class="text-white mx-2 text-decoration-none" aria-label="Button"><i class="fa-brands fa-youtube"></i></a>
</div>
</div>
</div>
</footer>
@code { @code {
[Parameter] [Parameter]
public Guid? invitationId { get; set; } public Guid? invitationId { get; set; }
@ -257,7 +232,7 @@
private IEnumerable<string> comuneList { get; set; } private IEnumerable<string> comuneList { get; set; }
private IEnumerable<string> provinciaList { get; set; } private IEnumerable<string> provinciaList { get; set; }
private IEnumerable<DestinazioneViewModel> destinazioniList { get; set; } private IEnumerable<DestinazioneViewModel> destinazioniList { get; set; }
private IEnumerable<LookupViewModel<int>> tipologiaList { get; set; } private IEnumerable<LookupViewModel<Guid>> tipologiaList { get; set; }
private IEnumerable<string> esperienzaList { get; set; } private IEnumerable<string> esperienzaList { get; set; }
private IEnumerable<LookupViewModel<int>> ruoloList { get; set; } private IEnumerable<LookupViewModel<int>> ruoloList { get; set; }
@ -283,7 +258,9 @@
provinciaList = new List<string>() { "BS" }; provinciaList = new List<string>() { "BS" };
esperienzaList = new List<string>() { "Si", "No" }; esperienzaList = new List<string>() { "Si", "No" };
var eUtils = new EnumUtils(); var eUtils = new EnumUtils();
tipologiaList = eUtils.GetEnumList<ClienteTipo>();
tipologiaList = (await _managerService.TipologiaClienteService.RicercaQueryable(x => x.Eliminato == false))
.Select(x => new LookupViewModel<Guid>(x.Id, x.Nome)).ToList();
ruoloList = eUtils.GetEnumList<RuoloTipo>(); ruoloList = eUtils.GetEnumList<RuoloTipo>();
} }
} }
@ -313,11 +290,13 @@
private async Task onIscrizioneSave() private async Task onIscrizioneSave()
{ {
var model = new IscrizioneEvento() { EventoId = invito.EventoId, InvitoEventoId = invito.Id, ClienteId = invito.ClienteId, DestinazioneId = iscrizione.Destinazione.Id }; var model = new IscrizioneEvento() {
EventoId = invito.EventoId,
InvitoEventoId = invito.Id,
ClienteId = invito.ClienteId,
DestinazioneId = iscrizione.DestinazioneId };
model = iscrizione.Map(model); model = iscrizione.Map(model);
model.TipologiaCliente = await _managerService.TipologiaClienteService.RicercaPer(x => x.Id == iscrizione.TipologiaClienteId && x.Eliminato == false);
// TODO: Implementazione generazione QR Code
model.QrCodeCode = Guid.NewGuid().ToString();
await _managerService.IscrizioneEventoService.Salva(model); await _managerService.IscrizioneEventoService.Salva(model);

View File

@ -1,5 +1,6 @@
@attribute [Authorize] @attribute [Authorize]
@page "/management/Clienti" @page "/management/Clienti"
@using ClosedXML.Excel
@using Microsoft.EntityFrameworkCore @using Microsoft.EntityFrameworkCore
@using StandManager.Model @using StandManager.Model
@ -21,6 +22,8 @@
</div> </div>
<div class="col-auto ms-auto"> <div class="col-auto ms-auto">
<div class="btn-list"> <div class="btn-list">
<RadzenUpload class="btn-5 d-none d-sm-inline-block" Change=@onUpload ChooseText="Importa da excel" />
<a href="/management/Clienti/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block"> <a href="/management/Clienti/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
Nuovo cliente Nuovo cliente
</a> </a>
@ -29,7 +32,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="card"> <div class="card">
<div class="table-responsive"> <div class="table-responsive">
<RadzenDataGrid @ref="clientiGrid" AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.CheckBoxList" AllowSorting="true" PageSize="5" <RadzenDataGrid @ref="clientiGrid" AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.CheckBoxList" AllowSorting="true" PageSize="25"
AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true"
Data="@clienti" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single"> Data="@clienti" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single">
<Columns> <Columns>
@ -93,4 +96,55 @@
.Select(x => (ClienteViewModel)x).ToList(); .Select(x => (ClienteViewModel)x).ToList();
} }
} }
private async Task onUpload(UploadChangeEventArgs args)
{
var file = args.Files.FirstOrDefault();
if (file == null && (!file.Name.EndsWith(".xlsx") || !file.Name.EndsWith(".xls")))
{
await _dialogService.Alert("Il file selezionato non è nel formato corretto.", "Errore");
return;
}
try
{
await using var uploadStream = file.OpenReadStream(10_000_000);
await using var ms = new MemoryStream();
await uploadStream.CopyToAsync(ms);
ms.Position = 0;
using var workbook = new XLWorkbook(ms);
var ws = workbook.Worksheet(1);
var usedRange = ws.RangeUsed();
var ragioniSociali = ws.RangeUsed().RowsUsed().Skip(1).Select(r => new { Rid = r.Cell(1).GetString(), RagioneSociale = r.Cell(4).GetString() }).Distinct().ToList();
foreach (var cliente in ragioniSociali)
{
var righeCliente = usedRange.RowsUsed().Where(r => r.Cell(1).GetString() == cliente.Rid).ToList();
var clienteDb = await _managerService.ClienteService.RicercaPer(
x => x.Rid == cliente.Rid && x.Eliminato == false,
includi: x => x.Include(i => i.Destinazioni),
solaLettura: false) ?? new Cliente();
clienteDb = mapCliente(clienteDb, righeCliente);
}
ms.Close();
}
catch (Exception ex)
{
var er = ex.Message;
await _dialogService.Alert("Si è verificato un errore durante l'importazione del file.", "Errore");
}
}
private Cliente mapCliente(Cliente model, List<IXLRangeRow> rows)
{
var firstRow = rows.First();
model.Rid = firstRow.Cell(1).GetString();
model.RagioneSociale = firstRow.Cell(4).GetString();
return model;
}
} }

View File

@ -92,7 +92,7 @@
</div> </div>
<div class="col-3 mb-3"> <div class="col-3 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Tipologia</RadzenText> <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Tipologia</RadzenText>
<RadzenDropDown Style="width: 100%" TValue="int" @bind-Value=@cliente.TipologiaClienteInt Data=@tipologiaCliente TextProperty="Description" ValueProperty="Key" Name="tipologiaClienteDrop" /> <RadzenDropDown Style="width: 100%" TValue="Guid ?" @bind-Value=@cliente.TipologiaClienteId Data=@tipologiaCliente TextProperty="Nome" ValueProperty="Id" Name="tipologiaClienteDrop" />
</div> </div>
<div class="col-3 mb-3"> <div class="col-3 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Stato</RadzenText> <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Stato</RadzenText>
@ -174,7 +174,7 @@
private ClienteViewModel cliente { get; set; } = new(); private ClienteViewModel cliente { get; set; } = new();
private IEnumerable<UtenteViewModel> agenti { get; set; } = new List<UtenteViewModel>(); private IEnumerable<UtenteViewModel> agenti { get; set; } = new List<UtenteViewModel>();
private List<LookupViewModel<int>> tipologiaCliente { get; set; } = new List<LookupViewModel<int>>(); private List<TipologiaClienteViewModel> tipologiaCliente { get; set; } = new();
private List<LookupViewModel<int>> statoCliente { get; set; } = new List<LookupViewModel<int>>(); private List<LookupViewModel<int>> statoCliente { get; set; } = new List<LookupViewModel<int>>();
RadzenDataGrid<DestinazioneViewModel> destinazioniGrid; RadzenDataGrid<DestinazioneViewModel> destinazioniGrid;
@ -197,11 +197,11 @@
agenti = (await _managerService.UtenteService.RicercaQueryable(x => x.Eliminato == false, ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome))) agenti = (await _managerService.UtenteService.RicercaQueryable(x => x.Eliminato == false, ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome)))
.Select(x => (UtenteViewModel)x).ToList(); .Select(x => (UtenteViewModel)x).ToList();
var eUtils = new EnumUtils(); var eUtils = new EnumUtils();
tipologiaCliente = eUtils.GetEnumList<ClienteTipo>(); tipologiaCliente = (await _managerService.TipologiaClienteService.RicercaQueryable(ordinamento: x => x.OrderBy(y => y.Nome))).Select(x => (TipologiaClienteViewModel)x).ToList();
statoCliente = eUtils.GetEnumList<ClienteStato>(); statoCliente = eUtils.GetEnumList<ClienteStato>();
if (ClienteId.GetValueOrDefault() != Guid.Empty) if (ClienteId.GetValueOrDefault() != Guid.Empty)
cliente = await _managerService.ClienteService.RicercaPer(x => x.Id == ClienteId, includi: x => x.Include(y => y.Agente).Include(y => y.Destinazioni).ThenInclude(z => z.Agente)); cliente = await _managerService.ClienteService.RicercaPer(x => x.Id == ClienteId, includi: x => x.Include(y => y.Agente).Include(y => y.TipologiaCliente).Include(y => y.Destinazioni).ThenInclude(z => z.Agente));
else else
cliente = new ClienteViewModel(); cliente = new ClienteViewModel();
@ -234,6 +234,12 @@
if (cliente.AgenteId.GetValueOrDefault() != Guid.Empty) if (cliente.AgenteId.GetValueOrDefault() != Guid.Empty)
model.Agente = await _managerService.UtenteService.RicercaPer(x => x.Id == cliente.AgenteId); model.Agente = await _managerService.UtenteService.RicercaPer(x => x.Id == cliente.AgenteId);
if (cliente.TipologiaClienteId.GetValueOrDefault() != Guid.Empty)
{
model.TipologiaClienteId = cliente.TipologiaClienteId;
model.TipologiaCliente = await _managerService.TipologiaClienteService.RicercaPer(x => x.Id == cliente.TipologiaClienteId);
}
if (cliente.Id == Guid.Empty) if (cliente.Id == Guid.Empty)
{ {
var destinazione = new Destinazione() { Cliente = model }; var destinazione = new Destinazione() { Cliente = model };

View File

@ -29,7 +29,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="card"> <div class="card">
<div class="table-responsive"> <div class="table-responsive">
<RadzenDataGrid @ref="eventiGrid" AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.CheckBoxList" AllowSorting="true" PageSize="5" <RadzenDataGrid @ref="eventiGrid" AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.CheckBoxList" AllowSorting="true" PageSize="25"
AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true"
Data="@eventi" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single"> Data="@eventi" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single">
<Columns> <Columns>

View File

@ -27,7 +27,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="card"> <div class="card">
<div class="table-responsive"> <div class="table-responsive">
<RadzenDataGrid @ref="userGrid" AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.CheckBoxList" AllowSorting="true" PageSize="15" <RadzenDataGrid @ref="userGrid" AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.CheckBoxList" AllowSorting="true" PageSize="25"
AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true"
Data="@utenti" ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single"> Data="@utenti" ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single">
<Columns> <Columns>

View File

@ -2,6 +2,7 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace StandManager.Model; namespace StandManager.Model;
public class ClienteViewModel public class ClienteViewModel
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
@ -21,8 +22,8 @@ public class ClienteViewModel
public List<DestinazioneViewModel> Destinazioni { get; set; } public List<DestinazioneViewModel> Destinazioni { get; set; }
public string Rid { get; set; } public string Rid { get; set; }
public ClienteTipo TipologiaCliente { get; set; } public TipologiaClienteViewModel TipologiaCliente { get; set; }
public int TipologiaClienteInt { get; set; } public Guid? TipologiaClienteId { get; set; }
public ClienteStato StatoCliente { get; set; } public ClienteStato StatoCliente { get; set; }
public int StatoClienteInt { get; set; } public int StatoClienteInt { get; set; }
@ -47,7 +48,7 @@ public class ClienteViewModel
RagioneSociale = model.RagioneSociale, RagioneSociale = model.RagioneSociale,
Rid = model.Rid, Rid = model.Rid,
TipologiaCliente = model.TipologiaCliente, TipologiaCliente = model.TipologiaCliente,
TipologiaClienteInt = (int)model.TipologiaCliente, TipologiaClienteId = model.TipologiaCliente?.Id ?? Guid.Empty,
StatoCliente = model.StatoCliente, StatoCliente = model.StatoCliente,
StatoClienteInt = (int)model.StatoCliente StatoClienteInt = (int)model.StatoCliente
}; };
@ -64,7 +65,6 @@ public class ClienteViewModel
model.EmailInvito = EmailInvito; model.EmailInvito = EmailInvito;
model.NumeroTelefono = NumeroTelefono; model.NumeroTelefono = NumeroTelefono;
model.Rid = Rid; model.Rid = Rid;
model.TipologiaCliente = (ClienteTipo)TipologiaClienteInt;
model.StatoCliente = (ClienteStato)StatoClienteInt; model.StatoCliente = (ClienteStato)StatoClienteInt;
return model; return model;
@ -84,3 +84,20 @@ public class ClienteViewModel
return model; return model;
} }
} }
public class TipologiaClienteViewModel
{
public Guid Id { get; set; }
public string Nome { get; set; }
public static implicit operator TipologiaClienteViewModel(TipologiaCliente model)
{
return model == null
? null
: new TipologiaClienteViewModel()
{
Id = model.Id,
Nome = model.Nome
};
}
}

View File

@ -11,13 +11,12 @@ public class IscrizioneEventoViewModel
public ClienteViewModel Cliente { get; set; } public ClienteViewModel Cliente { get; set; }
[Required(ErrorMessage = "La destinazione è obbligatoria")] [Required(ErrorMessage = "La destinazione è obbligatoria")]
public DestinazioneViewModel Destinazione { get; set; } public Guid DestinazioneId { get; set; }
[Range(1, int.MaxValue, ErrorMessage = "Inserire un numero di partecipanti validi")] [Range(1, int.MaxValue, ErrorMessage = "Inserire un numero di partecipanti validi")]
public int Partecipanti { get; set; } public int Partecipanti { get; set; }
[Required(ErrorMessage = "Le note sono obbligatorie")] [Required(ErrorMessage = "Le note sono obbligatorie")]
public string Note { get; set; } public string Note { get; set; }
public string QrCodeCode { get; set; }
public bool ScanCompleto { get; set; } public bool ScanCompleto { get; set; }
public DateTime? DataScan { get; set; } public DateTime? DataScan { get; set; }
[Required(ErrorMessage = "Il nome è obbigatorio")] [Required(ErrorMessage = "Il nome è obbigatorio")]
@ -38,10 +37,8 @@ public class IscrizioneEventoViewModel
public string RagioneSociale { get; set; } public string RagioneSociale { get; set; }
[Required(ErrorMessage = "Il campo è obbigatorio")] [Required(ErrorMessage = "Il campo è obbigatorio")]
public string EsperienzaConDAC { get; set; } public string EsperienzaConDAC { get; set; }
public ClienteTipo Tipologia { get; set; }
[Required(ErrorMessage = "La tipologia è obbigatoria")] [Required(ErrorMessage = "La tipologia è obbigatoria")]
public int? TipologiaInt { get; set; } public Guid TipologiaClienteId { get; set; }
public RuoloTipo Ruolo { get; set; } public RuoloTipo Ruolo { get; set; }
[Required(ErrorMessage = "Il ruolo è obbigatorio")] [Required(ErrorMessage = "Il ruolo è obbigatorio")]
public int? RuoloInt { get; set; } public int? RuoloInt { get; set; }
@ -49,43 +46,10 @@ public class IscrizioneEventoViewModel
public bool PresaVisioneDatiPersonali { get; set; } public bool PresaVisioneDatiPersonali { get; set; }
public static implicit operator IscrizioneEventoViewModel(IscrizioneEvento model)
{
return model == null
? null
: new IscrizioneEventoViewModel()
{
Id = model.Id,
Evento = model.Evento,
InvitoEvento = model.InvitoEvento,
Cliente = model.Cliente,
Destinazione = model.Destinazione,
Partecipanti = model.Partecipanti,
Note = model.Note,
QrCodeCode = model.QrCodeCode,
ScanCompleto = model.ScanCompleto,
DataScan = model.DataScan,
Nome = model.Nome,
Cognome = model.Cognome,
Email = model.Email,
NumeroTelefono = model.NumeroTelefono,
Provincia = model.Provincia,
Comune = model.Comune,
Cap = model.Cap,
RagioneSociale = model.RagioneSociale,
EsperienzaConDAC = model.EsperienzaConDAC,
Tipologia = model.Tipologia,
TipologiaInt = (int)model.Tipologia,
Ruolo = model.Ruolo,
RuoloInt = (int)model.Ruolo,
};
}
public IscrizioneEvento Map(IscrizioneEvento model) public IscrizioneEvento Map(IscrizioneEvento model)
{ {
model.Partecipanti = Partecipanti; model.Partecipanti = Partecipanti;
model.Note = Note; model.Note = Note;
model.QrCodeCode = QrCodeCode;
model.ScanCompleto = ScanCompleto; model.ScanCompleto = ScanCompleto;
model.DataScan = DataScan; model.DataScan = DataScan;
model.Nome = Nome; model.Nome = Nome;
@ -97,8 +61,6 @@ public class IscrizioneEventoViewModel
model.Cap = Cap; model.Cap = Cap;
model.RagioneSociale = RagioneSociale; model.RagioneSociale = RagioneSociale;
model.EsperienzaConDAC = EsperienzaConDAC; model.EsperienzaConDAC = EsperienzaConDAC;
model.Tipologia = (ClienteTipo)TipologiaInt;
model.Ruolo = (RuoloTipo)RuoloInt;
return model; return model;
} }

View File

@ -8,6 +8,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ClosedXML" Version="0.105.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.22" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.22" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.22" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.22" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.22" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.22" />

View File

@ -1,376 +1,8 @@
html { .footer {
font-size: 14px; font-size: 0.875rem; /* stesso size Tabler */
} }
@media (min-width: 768px) { .footer i[class^="fa-"],
html { .footer i[class*=" fa-"] {
font-size: 16px; font-size: 1em;
} }
}
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}
html {
position: relative;
min-height: 100%;
}
body {
margin-bottom: 60px;
}
:root {
--tblr-primary: #90bd22 !important;
}
.card-selectable {
min-height: 240px;
display: flex;
flex-direction: column;
justify-content: flex-end; /* permette di vedere prima l'immagine poi il titolo in fondo */
margin-bottom: 20px; /* spazio tra le righe */
overflow: visible;
}
.card-selectable-opt {
display: flex;
flex-direction: column;
justify-content: flex-end; /* permette di vedere prima l'immagine poi il titolo in fondo */
margin-bottom: 20px; /* spazio tra le righe */
overflow: visible;
}
.card-widget-image-vert-s {
background-size: contain; /* Cambiato da auto 100% a cover */
background-position: center;
background-repeat: no-repeat;
height: 50px;
min-height: 50px;
max-height: 50px;
border-radius: 8px 8px 0 0;
overflow: hidden; /* Nasconde tutto ciò che esce dal box */
}
.card-widget-image-vert-m {
background-size: contain; /* Cambiato da auto 100% a cover */
background-position: center;
background-repeat: no-repeat;
height: 100px;
min-height: 100px;
max-height: 100px;
border-radius: 8px 8px 0 0;
overflow: hidden; /* Nasconde tutto ciò che esce dal box */
}
.card-widget-image-vert-l {
background-size: contain; /* Cambiato da auto 100% a cover */
background-position: center;
background-repeat: no-repeat;
height: 150px;
min-height: 150px;
max-height: 150px;
border-radius: 8px 8px 0 0;
overflow: hidden; /* Nasconde tutto ciò che esce dal box */
}
.card-widget-image-vert-xl {
background-size: contain; /* Cambiato da auto 100% a cover */
background-position: center;
background-repeat: no-repeat;
height: 200px;
min-height: 200px;
max-height: 200px;
border-radius: 8px 8px 0 0;
overflow: hidden; /* Nasconde tutto ciò che esce dal box */
}
.card-widget-title {
width: 100%;
background: #f5f5f5 !important;
color: #222 !important;
display: block;
padding: 8px 16px;
border-radius: 0 0 8px 8px;
margin: 0;
min-height: 44px;
border-top: 1px solid #ececec;
box-shadow: 0 1px 4px rgba(0,0,0,0.04);
transition: background 0.2s;
/* Aggiungi:
margin-bottom per separare la card dalla riga sotto
*/
margin-bottom: 2px;
}
.card-widget-image {
background-size:cover;
background-position:center;
height:75px;
min-height:75px;
max-height:75px;
}
.card-widget {
height:75px;
min-height:75px;
max-height:75px;
}
.card-color-preview-s {
height: 50px;
min-height: 50px;
max-height: 50px;
border-radius: 8px 8px 0 0;
width: 100%;
/* Così come l'immagine: parte alta della card */
box-shadow: 0 1px 4px rgba(0,0,0,0.04);
}
.card-color-preview-m {
height: 100px;
min-height: 100px;
max-height: 100px;
border-radius: 8px 8px 0 0;
width: 100%;
/* Così come l'immagine: parte alta della card */
box-shadow: 0 1px 4px rgba(0,0,0,0.04);
}
.card-color-preview-l {
height: 150px;
min-height: 150px;
max-height: 150px;
border-radius: 8px 8px 0 0;
width: 100%;
/* Così come l'immagine: parte alta della card */
box-shadow: 0 1px 4px rgba(0,0,0,0.04);
}
.card-color-preview-xl {
height: 200px;
min-height: 200px;
max-height: 200px;
border-radius: 8px 8px 0 0;
width: 100%;
/* Così come l'immagine: parte alta della card */
box-shadow: 0 1px 4px rgba(0,0,0,0.04);
}
.optSelected{
border: 3px solid green !important;
}
.timeline{
position:relative;
padding-left: 32px;
}
.timeline-step {
position:relative;
margin-bottom:24px;
min-height:36px;
}
.timeline-step:last-child {
margin-bottom:0;
}
.timeline-flag {
position:absolute;
left:-28px;
top:3px;
width:20px;
height:20px;
border-radius:50%;
background:#e0e0e0;
border:2px solid #bbb;
display:inline-block;
transition:background 0.2s, border 0.2s;
text-align:center;
font-size:14px;
line-height:18px;
}
.timeline-step.completed{
cursor: pointer;
}
.timeline-step.completed .timeline-flag {
background:#28a745;
border-color:#1e7e34;
color:#fff;
}
.timeline-step .timeline-flag:after{
content: '\2713';
opacity:0;
transition:opacity 0.2s;
font-weight:bold;
display:block;
}
.timeline-step.completed .timeline-flag:after{
opacity:1;
}
/*Allargo la dimensione della pagina*/
@media (min-width: 1400px) {
.container, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl {
max-width: 90%;
}
}
/*Mirino*/
/* === Contenitore principale === */
.trim-stage.compact{
position:relative;
width:min(560px, 100%);
margin:0 auto;
height:240px; /* Altezza compatta */
background:#fff;
border:1px solid #e5e7eb;
border-radius:16px;
box-shadow:0 4px 12px rgba(0,0,0,.06);
}
/* === Immagine centrale === */
.trim-image{
position:absolute;
inset:20% 22%; /* margini interni */
max-width:56%;
max-height:60%;
object-fit:contain;
background:#fff;
border:1px dashed #cbd5e1;
border-radius:12px;
}
/* === Controlli (pillole) === */
.trim-ctrl{
position:absolute;
display:flex;
align-items:center;
gap:.5rem;
padding:.25rem .5rem;
background:#ffffffd9;
border:1px solid #e5e7eb;
border-radius:999px;
box-shadow:0 2px 6px rgba(0,0,0,.06);
}
/* Etichette "Sopra/Sotto/Sinistra/Destra" */
.trim-label{
font-size:.75rem;
font-weight:600;
color:#334155;
margin:0;
}
/* Wrapper per select + unità */
.trim-input{
display:flex;
align-items:center;
gap:.25rem;
}
/* Dropdown compatto */
.trim-input .form-control{
min-width: 120px;
}
/* Etichetta "mm" */
.unit-label{
font-size:.75rem;
font-weight:500;
color:#475569;
}
/* === Posizionamenti attorno allimmagine === */
.trim-ctrl-top { top:0; left:50%; transform:translate(-50%,-40%); }
.trim-ctrl-bottom{ bottom:0; left:50%; transform:translate(-50%,40%); }
.trim-ctrl-left { left:0; top:50%; transform:translate(-40%,-50%); }
.trim-ctrl-right { right:0; top:50%; transform:translate(40%,-50%); }
/* === Responsività (mobile) === */
@media (max-width: 576px){
.trim-stage.compact{
height:auto;
padding-bottom: 260px; /* spazio per i controlli sotto */
}
.trim-ctrl{
position:static;
transform:none;
margin:.35rem auto 0;
width:min(420px, 92%);
justify-content:space-between;
}
}
.trim-stage.compact .trim-image{
position:absolute;
top:50%;
left:50%;
transform:translate(-50%, -50%); /* centra in entrambi gli assi */
max-width:56%;
max-height:60%;
width:auto;
height:auto;
object-fit:contain;
background:#fff;
border:1px dashed #cbd5e1;
border-radius:12px;
}
/* (facoltativo) se vuoi leggermente più grande o più piccolo */
@media (min-width: 768px){
.trim-stage.compact .trim-image{
max-width:60%;
max-height:70%;
}
}
.step-no-border{
padding-left: 0 !important;
border-left: 0 !important;
}
.modal-config{
margin-left: 20px !important;
margin-right: 20px !important;
}
@media (min-width: 576px) {
.modal-config{
max-width: 97% !important;
}
}
.reset-flash {
--flash-color: var(--tblr-info, rgb(var(--bs-info-rgb, 58,167,255)));
outline: 2px solid var(--flash-color);
border-radius: .6rem;
will-change: box-shadow, transform, opacity;
animation: resetFlashSmooth 1.6s cubic-bezier(.22,.61,.36,.50) both;
}
@keyframes resetFlashSmooth {
0% {
box-shadow: 0 0 0 .75rem color-mix(in srgb, var(--flash-color) 45%, transparent);
transform: translateZ(0) scale(1.01);
opacity: 1;
}
35% {
box-shadow: 0 0 0 .55rem color-mix(in srgb, var(--flash-color) 32%, transparent);
transform: scale(1.005);
}
70% {
box-shadow: 0 0 0 .25rem color-mix(in srgb, var(--flash-color) 18%, transparent);
transform: scale(1);
}
100% {
box-shadow: 0 0 0 0 color-mix(in srgb, var(--flash-color) 0%, transparent);
opacity: 1;
}
}