- IscrizioneEvento: creazione delle iscrizioni

This commit is contained in:
2025-12-04 18:03:42 +01:00
parent 1a49be764c
commit 0cac2ec202
7 changed files with 244 additions and 18 deletions

View File

@ -12,6 +12,9 @@ public class InvitoEvento : EntitaBase
[ForeignKey(nameof(Cliente))]
public Guid? ClienteId { get; set; }
public Cliente Cliente { get; set; }
[InverseProperty(nameof(IscrizioneEvento.InvitoEvento))]
public List<IscrizioneEvento> IscrizioniEvento { get; set; }
}
public class IscrizioneEvento : EntitaBase

View File

@ -3,4 +3,7 @@ using StandManager.Domain.Entita;
namespace StandManager.Service.Interfaces;
public interface IIscrizioneEventoService : ITService<IscrizioneEvento>{}
public interface IIscrizioneEventoService : ITService<IscrizioneEvento>
{
Task<IscrizioneEvento> Salva(IscrizioneEvento model);
}

View File

@ -13,4 +13,21 @@ public class IscrizioneEventoService : TService<IscrizioneEvento>, IIscrizioneEv
{
_unitOfWork = unitOfWork;
}
public async Task<IscrizioneEvento> Salva(IscrizioneEvento entita)
{
bool isNuovaEntita = entita.Id == Guid.Empty;
entita.DataCreazione = isNuovaEntita ? DateTime.Now : entita.DataCreazione;
entita.DataModifica = isNuovaEntita == false ? DateTime.Now : null;
entita.IdUtenteCreazione = isNuovaEntita ? null : entita.IdUtenteCreazione;
entita.IdUtenteModifica = isNuovaEntita == false ? null : null;
if (isNuovaEntita)
await _unitOfWork.GetRepository<IscrizioneEvento>().Put(entita);
int result = await _unitOfWork.Salva();
return entita;
}
}

View File

@ -1,5 +1,6 @@
@using Microsoft.AspNetCore.Authentication
@inherits LayoutComponentBase
@inject NavigationManager NavManager
<RadzenComponents @rendermode="InteractiveAuto" />
@ -44,7 +45,7 @@
<div class="col">
<!-- BEGIN NAVBAR MENU -->
<ul class="navbar-nav">
<li class="nav-item active">
<li class="nav-item @GetActiveClass("/management")">
<a class="nav-link" href="/management">
<span class="nav-link-icon d-md-none d-lg-inline-block">
<i class="fa-solid fa-house"></i>
@ -52,7 +53,7 @@
<span class="nav-link-title"> Home </span>
</a>
</li>
<li class="nav-item">
<li class="nav-item @GetActiveClass("/management/Utenti")">
<a class="nav-link" href="/management/Utenti">
<span class="nav-link-icon d-md-none d-lg-inline-block">
<i class="fa-solid fa-house"></i>
@ -60,7 +61,7 @@
<span class="nav-link-title"> Utenti </span>
</a>
</li>
<li class="nav-item">
<li class="nav-item @GetActiveClass("/management/Clienti")">
<a class="nav-link" href="/management/Clienti">
<span class="nav-link-icon d-md-none d-lg-inline-block">
<i class="fa-solid fa-address-card"></i>
@ -68,7 +69,7 @@
<span class="nav-link-title"> Clienti </span>
</a>
</li>
<li class="nav-item">
<li class="nav-item @GetActiveClass("/management/Eventi")">
<a class="nav-link" href="/management/Eventi">
<span class="nav-link-icon d-md-none d-lg-inline-block">
<i class="fa-solid fa-address-card"></i>
@ -91,10 +92,27 @@
[CascadingParameter]
public HttpContext? httpContext { get; set; }
private string currentUrl = string.Empty;
protected override async Task OnInitializedAsync()
{
base.OnInitializedAsync();
var context = httpContext.GetRouteData();
currentUrl = NavManager.ToBaseRelativePath(NavManager.Uri);
}
private string GetActiveClass(string href)
{
string currentClean = currentUrl.Split("management").Last();
string hrefClean = href.Split("management").Last();
if (currentClean.Contains("?"))
currentClean = currentClean.Substring(0, currentClean.IndexOf("?"));
var isActive = (currentClean.Contains(hrefClean, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(hrefClean)
|| (string.IsNullOrEmpty(hrefClean) && string.IsNullOrEmpty(currentClean)));
return isActive ? "active" : "";
}
}

View File

@ -4,24 +4,109 @@
@using Microsoft.EntityFrameworkCore
@using StandManager.Components.Layout
@using StandManager.Model
@inject AuthenticationStateProvider auth
@inject BodyClassService BodyClass
@rendermode InteractiveServer
<PageTitle>Evento</PageTitle>
<PageTitle>Iscrizioni Evento</PageTitle>
<header class="hero pb-0">
<div class="container">
@if (invitationId.HasValue)
@if (invitationId.HasValue && invito != null)
{
<h1 class="hero-title">Ciao @invito.Cliente.RagioneSociale - Sei stato invitato a: @invito.Evento.Titolo</h1>
<p class="hero-description mt-4">
L'evento si terrà dal @invito.Evento.DataDa.ToString("dd/MM/yyyy") al @invito.Evento.DataA.ToString("dd/MM/yyyy"), presso: @invito.Evento.Luogo
</p>
<div class="mb-2">
<h1 class="hero-title">Ciao @invito.Cliente.RagioneSociale - Sei stato invitato a: @invito.Evento.Titolo</h1>
<p class="hero-description mt-4">
L'evento si terrà dal @invito.Evento.DataDa.ToString("dd/MM/yyyy") al @invito.Evento.DataA.ToString("dd/MM/yyyy"), presso: @invito.Evento.Luogo
</p>
</div>
@if (destinazioniList.Count() > 0)
{
<div class="row row-cards">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
Compila le destinazioni mancanti
</div>
<div class="card-body">
<div class="row g-5">
<EditForm Model="iscrizione" OnValidSubmit="onIscrizioneSave" FormName="iscrizioneForm">
<DataAnnotationsValidator />
<div class="col-12">
<div class="row">
<div class="col-8 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Destinazione</RadzenText>
<RadzenDropDown @bind-Value="@iscrizione.Destinazione" Style="width: 100%" TextProperty="RagioneSociale"
Data="@destinazioniList" Size="ButtonSize.Small" />
<ValidationMessage For="@(() => iscrizione.Destinazione)" />
</div>
<div class="col-4 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Numero di partecipanti</RadzenText>
<RadzenNumeric ShowUpDown="false" TValue="int" TextAlign="TextAlign.Right" Style="width: 100%" aria-label="Partecipanti" @bind-Value="@iscrizione.Partecipanti" />
<ValidationMessage For="@(() => iscrizione.Partecipanti)" />
</div>
</div>
<div class="row">
<div class="col-12 mb-3">
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Note</RadzenText>
<RadzenTextArea @bind-Value="@iscrizione.Note" Style="width: 100%;" Rows="3" />
<ValidationMessage For="@(() => iscrizione.Note)" />
</div>
</div>
<div class="row">
<div class="col-3 mb-3">
<button type="button" class="btn btn-default w-100" @onclick="backToHome">
Torna all'inserimento codice
</button>
</div>
<div class="col-3 mb-3">
<button type="submit" class="btn btn-primary w-100">
Salva
</button>
</div>
</div>
</div>
</EditForm>
</div>
</div>
</div>
</div>
</div>
}
else
{
<div class="text-danger mt-1">Non sono presenti destinazioni da compilare per questo evento!</div>
}
}
else
{
<h1 class="hero-title">Iscriviti ad un evento, inserisci il tuo codice di invito</h1>
<div class="mb-2">
<h1 class="hero-title">Iscriviti ad un evento, inserisci il tuo codice di invito</h1>
</div>
<div class="col-12">
<div class="row">
<div class="col-9 mb-3">
<RadzenTextBox @bind-Value="@invitationCode" Placeholder="Inserirci il codice invito" Style="width: 100%;" />
@if (!string.IsNullOrEmpty(invalidCode))
{
<div class="text-danger mt-1">@invalidCode</div>
}
</div>
<div class="col-3 mb-3">
<button type="button" class="btn btn-primary w-100" @onclick="reloadWithCode">
Invia
</button>
</div>
</div>
</div>
}
</div>
</header>
@ -33,14 +118,29 @@
private InvitoEvento invito { get; set; }
[SupplyParameterFromForm]
private IscrizioneEventoViewModel iscrizione { get; set; } = new();
private IEnumerable<DestinazioneViewModel> destinazioniList { get; set; }
public string invitationCode { get; set; } = string.Empty;
private string invalidCode = string.Empty;
protected override async Task OnInitializedAsync()
{
base.OnInitializedAsync();
invito = invitationId.GetValueOrDefault() != Guid.Empty
? await _managerService.InvitoEventoService.RicercaPer(x => x.Id == invitationId && x.Eliminato == false,
includi: x => x.Include(y => y.Evento).Include(y => y.Cliente).ThenInclude(y => y.Destinazioni))
includi: x => x.Include(y => y.Evento).Include(y => y.Cliente).ThenInclude(y => y.Destinazioni).Include(y => y.IscrizioniEvento))
: new();
if(invito == null)
invalidCode = "Il codice inserito non risulta corretto";
else
{
var destinazioniIds = invito.IscrizioniEvento?.Select(x => x.DestinazioneId).ToList() ?? new List<Guid?>();
destinazioniList = (await _managerService.DestinazioneService.RicercaQueryable(filtro: x => x.ClienteId == invito.ClienteId && !destinazioniIds.Any(y => y == x.Id))).Select(x => (DestinazioneViewModel)x).ToList();
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
@ -48,4 +148,36 @@
if (firstRender)
await BodyClass.SetBodyClass("body-marketing body-gradient");
}
private void reloadWithCode()
{
if (Guid.TryParse(invitationCode, out Guid invitationCodeParsed))
{
_navManager.NavigateTo($"/{invitationCodeParsed}");
}
else
{
invalidCode = "Il codice inserito non risulta corretto";
}
}
private void backToHome()
{
_navManager.NavigateTo($"/");
}
private async Task onIscrizioneSave()
{
var model = new IscrizioneEvento() { EventoId = invito.EventoId, InvitoEventoId = invito.Id, ClienteId = invito.ClienteId, DestinazioneId = iscrizione.Destinazione.Id };
model = iscrizione.Map(model);
// TODO: Implementazione generazione QR Code
model.QrCodeCode = Guid.NewGuid().ToString();
await _managerService.IscrizioneEventoService.Salva(model);
_navManager.NavigateTo($"/");
}
}

View File

@ -112,7 +112,7 @@
model = destinazione.Map(model);
if (destinazione.AgenteId.GetValueOrDefault() != Guid.Empty)
model.Agente = await _managerService.UtenteService.RicercaPer(x => x.Id == destinazione.AgenteId);
model.AgenteId = destinazione.AgenteId;
await _managerService.DestinazioneService.Salva(model, idClaim);
_dialogService.Close(true);

View File

@ -0,0 +1,53 @@
using StandManager.Domain.Entita;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace StandManager.Model;
public class IscrizioneEventoViewModel
{
public Guid Id { get; set; }
public EventoViewModel Evento { get; set; }
public InvitoEvento InvitoEvento { get; set; }
public ClienteViewModel Cliente { get; set; }
[Required(ErrorMessage = "La destinazione è obbligatoria")]
public DestinazioneViewModel Destinazione { get; set; }
public int Partecipanti { get; set; }
[Required(ErrorMessage = "Le note sono obbligatorie")]
public string Note { get; set; }
public string QrCodeCode { get; set; }
public bool ScanCompleto { get; set; }
public DateTime? DataScan { 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
};
}
public IscrizioneEvento Map(IscrizioneEvento model)
{
model.Partecipanti = Partecipanti;
model.Note = Note;
model.QrCodeCode = QrCodeCode;
model.ScanCompleto = ScanCompleto;
model.DataScan = DataScan;
return model;
}
}