commit cliente
This commit is contained in:
@ -1,7 +1,98 @@
|
|||||||
@page "/anagrafiche/clienti"
|
@page "/anagrafiche/clienti"
|
||||||
|
@using Microsoft.EntityFrameworkCore
|
||||||
|
@using TecniStamp.Domain
|
||||||
|
@using TecniStamp.Model.Commesse
|
||||||
|
@using TecniStamp.Model.Common
|
||||||
|
@using TecniStamp.Utils
|
||||||
|
|
||||||
|
|
||||||
|
@rendermode InteractiveServer
|
||||||
|
@inject AuthenticationStateProvider auth
|
||||||
<PageTitle>Clienti</PageTitle>
|
<PageTitle>Clienti</PageTitle>
|
||||||
|
<Breadcrumb Items="BreadcrumbList" />
|
||||||
|
|
||||||
|
<main role="main">
|
||||||
|
<div class="container-fluid h-100 mt-5">
|
||||||
|
<div class="row justify-content-start">
|
||||||
|
<div class="row row-cards">
|
||||||
|
<div class="col-auto ms-auto">
|
||||||
|
<div class="btn-list">
|
||||||
|
<a href="/Anagrafiche/Clienti/Modifica" class="btn btn-primary btn-5 d-none d-sm-inline-block">
|
||||||
|
Nuovo Cliente
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<RadzenDataGrid @ref="clientiGrid" AllowFiltering="true" AllowColumnResize="true" AllowAlternatingRows="false" FilterMode="FilterMode.CheckBoxList" AllowSorting="true" PageSize="25"
|
||||||
|
AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true"
|
||||||
|
Data="@clienti" ColumnWidth="300px" LogicalFilterOperator="LogicalFilterOperator.Or" SelectionMode="DataGridSelectionMode.Single">
|
||||||
|
<Columns>
|
||||||
|
<RadzenDataGridColumn Property="@nameof(Cliente.RagioneSociale)" Title="Ragione sociale" Width="250px" />
|
||||||
|
<RadzenDataGridColumn Property="@nameof(Cliente.PartitaIva)" Title="Partita IVA" Width="250px" />
|
||||||
|
<RadzenDataGridColumn Property="@nameof(Cliente.Telefono)" Title="Telefono" Width="250px" />
|
||||||
|
<RadzenDataGridColumn Property="@nameof(Cliente.Email)" Title="Email" Width="250px" />
|
||||||
|
|
||||||
|
<RadzenDataGridColumn Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="200px">
|
||||||
|
<Template Context="cliente">
|
||||||
|
<RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => EditRow(cliente))" @onclick:stopPropagation="true" />
|
||||||
|
<RadzenButton Icon="delete" ButtonStyle="ButtonStyle.Danger" Variant="Variant.Flat" Size="ButtonSize.Medium" Shade="Shade.Lighter" class="rz-my-1 rz-ms-1" Click="@(args => DeleteRow(cliente))" @onclick:stopPropagation="true" />
|
||||||
|
</Template>
|
||||||
|
</RadzenDataGridColumn>
|
||||||
|
</Columns>
|
||||||
|
</RadzenDataGrid>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
List<Cliente> clienti;
|
||||||
|
RadzenDataGrid<Cliente> clientiGrid;
|
||||||
|
public List<BreadcrumbViewModel> BreadcrumbList { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Carica l’elenco dei clienti non eliminati, includendo l’agente,
|
||||||
|
/// e prepara i dati per la visualizzazione in pagina.
|
||||||
|
/// </summary>
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
|
||||||
|
clienti = (await _managerService.ClienteService.RicercaQueryable(
|
||||||
|
x => x.Eliminato == false,
|
||||||
|
ordinamento: x => x.OrderBy(y => y.RagioneSociale)))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
BreadcrumbList = await BreadcrumbUtils.BuildBreadcrumbByFeature(_managerService, "Clienti_Insert");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apre la pagina di modifica per il cliente selezionato.
|
||||||
|
/// </summary>
|
||||||
|
private async Task EditRow(ClienteViewModel cliente)
|
||||||
|
{
|
||||||
|
_navManager.NavigateTo($"/Anagrafiche/Clienti/Modifica/{cliente.Id}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Chiede conferma ed elimina il cliente scelto; se confermato,
|
||||||
|
/// aggiorna la lista ricaricandola dal database.
|
||||||
|
/// </summary>
|
||||||
|
private async Task DeleteRow(ClienteViewModel cliente)
|
||||||
|
{
|
||||||
|
var ok = await _dialogService.Confirm($"Vuoi davvero eliminare il cliente {cliente.RagioneSociale}?", "Conferma eliminazione", new ConfirmOptions { OkButtonText = "Sì", CancelButtonText = "No", Width = "400px" });
|
||||||
|
|
||||||
|
if (ok == true)
|
||||||
|
{
|
||||||
|
await _managerService.ClienteService.Elimina(cliente.Id, await MembershipUtils.GetUserId(auth));
|
||||||
|
clienti = (await _managerService.ClienteService.RicercaQueryable(x => x.Eliminato == false, ordinamento: x => x.OrderBy(y => y.RagioneSociale)))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,172 @@
|
|||||||
|
@page "/Anagrafiche/Clienti/Modifica"
|
||||||
|
@page "/Anagrafiche/Clienti/Modifica/{ClientiId:guid}"
|
||||||
|
@using TecniStamp.Domain
|
||||||
|
@using TecniStamp.Model.Commesse
|
||||||
|
@using TecniStamp.Model.Common
|
||||||
|
@using TecniStamp.Utils
|
||||||
|
|
||||||
|
<PageTitle>@pageTitle</PageTitle>
|
||||||
|
<Breadcrumb Items="BreadcrumbList" />
|
||||||
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
|
<div class="container-fluid h-100 mt-5">
|
||||||
|
<div class="row justify-content-start">
|
||||||
|
<div class="row row-cards">
|
||||||
|
<div class="col">
|
||||||
|
<h2 class="page-title">@pageTitle</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cards">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row g-5">
|
||||||
|
<EditForm Model="Model" OnValidSubmit="onClienteSave" FormName="editClienteForm">
|
||||||
|
<DataAnnotationsValidator />
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Ragione Sociale</RadzenText>
|
||||||
|
<RadzenTextBox Style="width: 100%" aria-label="Nome" @bind-Value="@Model.RagioneSociale" />
|
||||||
|
<ValidationMessage For="@(() => Model.RagioneSociale)" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Partita Iva</RadzenText>
|
||||||
|
<RadzenTextBox Style="width: 100%" aria-label="Cognome" @bind-Value="@Model.PartitaIva" />
|
||||||
|
<ValidationMessage For="@(() => Model.PartitaIva)" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Email</RadzenText>
|
||||||
|
<RadzenTextBox Style="width: 100%" aria-label="Email" @bind-Value="@Model.Email" />
|
||||||
|
<ValidationMessage For="@(() => Model.Email)" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Numero di Telefono</RadzenText>
|
||||||
|
<RadzenTextBox Style="width: 100%" aria-label="Email" @bind-Value="@Model.Telefono" />
|
||||||
|
<ValidationMessage For="@(() => Model.Telefono)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Via</RadzenText>
|
||||||
|
<RadzenTextBox Style="width: 100%" aria-label="Nome" @bind-Value="@Model.Via" />
|
||||||
|
<ValidationMessage For="@(() => Model.Via)" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Numero Civico</RadzenText>
|
||||||
|
<RadzenTextBox Style="width: 100%" aria-label="Cognome" @bind-Value="@Model.NumeroCivico" />
|
||||||
|
<ValidationMessage For="@(() => Model.NumeroCivico)" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Citta</RadzenText>
|
||||||
|
<RadzenTextBox Style="width: 100%" aria-label="Email" @bind-Value="@Model.Citta" />
|
||||||
|
<ValidationMessage For="@(() => Model.Citta)" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Provincia</RadzenText>
|
||||||
|
<RadzenTextBox Style="width: 100%" aria-label="Email" @bind-Value="@Model.Provincia" />
|
||||||
|
<ValidationMessage For="@(() => Model.Provincia)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">CAP</RadzenText>
|
||||||
|
<RadzenTextBox Style="width: 100%" aria-label="Nome" @bind-Value="@Model.CAP" />
|
||||||
|
<ValidationMessage For="@(() => Model.CAP)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<button type="button" class="btn btn-default w-100" @onclick="backToHome">
|
||||||
|
Annulla
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col-3 mb-3">
|
||||||
|
<button type="submit" class="btn btn-primary w-100">
|
||||||
|
Salva
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</EditForm>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter] public Guid? ClientiId { get; set; }
|
||||||
|
|
||||||
|
public ClienteViewModel Model { get; set; } = new();
|
||||||
|
private string pageTitle => Model?.Id == Guid.Empty ? "Nuovo Cliente" : $"Modifica Cliente {Model.RagioneSociale}";
|
||||||
|
|
||||||
|
public List<BreadcrumbViewModel> BreadcrumbList { get; set; } = new();
|
||||||
|
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
|
||||||
|
Model = ClientiId.GetValueOrDefault() == Guid.Empty
|
||||||
|
? new ClienteViewModel()
|
||||||
|
: await _managerService.ClienteService.RicercaPer(x => x.Id == ClientiId);
|
||||||
|
|
||||||
|
BreadcrumbList = await BreadcrumbUtils.BuildBreadcrumbByFeature(_managerService, "Clienti_Insert", "Modifica", "/Anagrafiche/Clienti");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Salva il cliente: recupera o crea il modello, applica i dati dalla UI,
|
||||||
|
/// collega l’agente, crea una destinazione di default se è un nuovo cliente
|
||||||
|
/// e poi salva usando l’ID dell’utente loggato, tornando alla lista clienti.
|
||||||
|
/// </summary>
|
||||||
|
private async Task onClienteSave()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var state = await _auth.GetAuthenticationStateAsync();
|
||||||
|
var idClaim = state.User.FindFirst("UserId")?.Value;
|
||||||
|
if (string.IsNullOrEmpty(idClaim))
|
||||||
|
{
|
||||||
|
// gestisci errore (utente non autenticato o claim mancante)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var model = await _managerService.ClienteService.RicercaPer(x => x.Id == Model.Id, solaLettura: false)
|
||||||
|
?? new Cliente();
|
||||||
|
|
||||||
|
model = Model.Map(model);
|
||||||
|
|
||||||
|
var clienteSalvato = await _managerService.ClienteService.Salva(model, Guid.Parse(idClaim));
|
||||||
|
_navManager.NavigateTo($"/Anagrafiche/Clienti");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await _dialogService.Alert("Si è verificato un'errore", "Errore", new AlertOptions() { OkButtonText = "Continua" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Torna all’elenco clienti senza applicare altre azioni.
|
||||||
|
/// </summary>
|
||||||
|
private void backToHome()
|
||||||
|
{
|
||||||
|
_navManager.NavigateTo("/Anagrafiche/Clienti");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -48,12 +48,12 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-4 mb-3">
|
<div class="col-3 mb-3">
|
||||||
<button type="button" class="btn btn-default w-100" @onclick="backToHome">
|
<button type="button" class="btn btn-default w-100" @onclick="backToHome">
|
||||||
Annulla
|
Annulla
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4 mb-3">
|
<div class="col-3 mb-3">
|
||||||
<button type="submit" class="btn btn-primary w-100">
|
<button type="submit" class="btn btn-primary w-100">
|
||||||
Salva
|
Salva
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -41,12 +41,12 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-4 mb-3">
|
<div class="col-3 mb-3">
|
||||||
<button type="button" class="btn btn-default w-100" @onclick="backToHome">
|
<button type="button" class="btn btn-default w-100" @onclick="backToHome">
|
||||||
Annulla
|
Annulla
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4 mb-3">
|
<div class="col-3 mb-3">
|
||||||
<button type="submit" class="btn btn-primary w-100">
|
<button type="submit" class="btn btn-primary w-100">
|
||||||
Salva
|
Salva
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -1,18 +1,40 @@
|
|||||||
using TecniStamp.Domain;
|
using Microsoft.IdentityModel.Abstractions;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using TecniStamp.Domain;
|
||||||
|
|
||||||
namespace TecniStamp.Model.Commesse;
|
namespace TecniStamp.Model.Commesse;
|
||||||
|
|
||||||
public class ClienteViewModel : BaseViewModel
|
public class ClienteViewModel : BaseViewModel
|
||||||
{
|
{
|
||||||
|
[Required(ErrorMessage = "La ragione sociale è obbligatoria")]
|
||||||
public string RagioneSociale { get; set; }
|
public string RagioneSociale { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "la partita iva è obbligatoria")]
|
||||||
public string PartitaIva { get; set; }
|
public string PartitaIva { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "il numero di telefono è obbligatorio")]
|
||||||
public string Telefono { get; set; }
|
public string Telefono { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "la mail è obbligatoria")]
|
||||||
|
[EmailAddress(ErrorMessage = "Formato email non valido")]
|
||||||
public string Email { get; set; }
|
public string Email { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "il CAP è obbligatoria")]
|
||||||
public string CAP { get; set; }
|
public string CAP { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "la città è obbligatoria")]
|
||||||
public string Citta { get; set; }
|
public string Citta { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "il numero civico è obbligatoria")]
|
||||||
public string NumeroCivico { get; set; }
|
public string NumeroCivico { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "la via è obbligatoria")]
|
||||||
public string Via { get; set; }
|
public string Via { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "la provincia è obbligatoria")]
|
||||||
public string Provincia { get; set; }
|
public string Provincia { get; set; }
|
||||||
|
|
||||||
public string? Note { get; set; }
|
public string? Note { get; set; }
|
||||||
public Guid? ComuneId { get; set; }
|
public Guid? ComuneId { get; set; }
|
||||||
public ComuneIstatViewModel Comune { get; set; }
|
public ComuneIstatViewModel Comune { get; set; }
|
||||||
@ -43,4 +65,20 @@ public class ClienteViewModel : BaseViewModel
|
|||||||
Id = model.Id
|
Id = model.Id
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Cliente Map(Cliente model)
|
||||||
|
{
|
||||||
|
model.RagioneSociale = RagioneSociale;
|
||||||
|
model.PartitaIva = PartitaIva;
|
||||||
|
model.Citta = Citta;
|
||||||
|
model.Email = Email;
|
||||||
|
model.Telefono = Telefono;
|
||||||
|
model.Citta = Citta;
|
||||||
|
model.CAP = CAP;
|
||||||
|
model.Provincia = Provincia;
|
||||||
|
model.Via = Via;
|
||||||
|
model.NumeroCivico = NumeroCivico;
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user