From c08e9325b41b5d3f6652055a2a82e237f31b2b56 Mon Sep 17 00:00:00 2001 From: Davide Sandrelli Date: Mon, 22 Dec 2025 15:05:07 +0100 Subject: [PATCH] - Import Comuni - Permessi modifica agente/capoarea in Clienti --- StandManager.Service/ComuneIstatService.cs | 16 ++++ .../Interfaces/IComuneIstatService.cs | 8 ++ .../Interfaces/IManagerService.cs | 1 + StandManager.Service/ManagerService.cs | 4 +- .../Management/Cliente_Destinazione.razor | 8 +- .../Components/Pages/Management/Clienti.razor | 23 +++++ .../Pages/Management/Clienti_Edit.razor | 96 ++++++++++++------- .../Pages/Management/Clienti_Import.razor | 38 ++++---- .../Pages/Management/Comuni_Import.razor | 73 ++++++++++++++ StandManager/Model/ClienteViewModel.cs | 4 + .../Model/ComuneIstatExcelViewModel.cs | 24 +++++ 11 files changed, 234 insertions(+), 61 deletions(-) create mode 100644 StandManager.Service/ComuneIstatService.cs create mode 100644 StandManager.Service/Interfaces/IComuneIstatService.cs create mode 100644 StandManager/Components/Pages/Management/Comuni_Import.razor create mode 100644 StandManager/Model/ComuneIstatExcelViewModel.cs diff --git a/StandManager.Service/ComuneIstatService.cs b/StandManager.Service/ComuneIstatService.cs new file mode 100644 index 0000000..3539110 --- /dev/null +++ b/StandManager.Service/ComuneIstatService.cs @@ -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 ComuneIstatService : TService, IComuneIstatService +{ + private readonly IStandManagerUnitOfWork _unitOfWork; + + public ComuneIstatService(IStandManagerUnitOfWork unitOfWork) : base(unitOfWork) + { + _unitOfWork = unitOfWork; + } +} diff --git a/StandManager.Service/Interfaces/IComuneIstatService.cs b/StandManager.Service/Interfaces/IComuneIstatService.cs new file mode 100644 index 0000000..b549667 --- /dev/null +++ b/StandManager.Service/Interfaces/IComuneIstatService.cs @@ -0,0 +1,8 @@ +using OAService.Service.Servizi.Interfacce; +using StandManager.Domain.Entita; + +namespace StandManager.Service.Interfaces; + +public interface IComuneIstatService : ITService +{ +} \ No newline at end of file diff --git a/StandManager.Service/Interfaces/IManagerService.cs b/StandManager.Service/Interfaces/IManagerService.cs index 2eea438..a07562b 100644 --- a/StandManager.Service/Interfaces/IManagerService.cs +++ b/StandManager.Service/Interfaces/IManagerService.cs @@ -3,6 +3,7 @@ public interface IManagerService { public IClienteService ClienteService{ get; set; } + public IComuneIstatService ComuneIstatService { get; set; } public IDestinazioneService DestinazioneService{ get; set; } public IEventoService EventoService{ get; set; } public IFeatureService FeatureService{ get; set; } diff --git a/StandManager.Service/ManagerService.cs b/StandManager.Service/ManagerService.cs index e3fb2dd..0546c83 100644 --- a/StandManager.Service/ManagerService.cs +++ b/StandManager.Service/ManagerService.cs @@ -4,12 +4,13 @@ namespace StandManager.Service; public class ManagerService : IManagerService { - public ManagerService(IUtenteService utenteService, IClienteService clienteService, IDestinazioneService destinazioneService, IEventoService eventoService, + public ManagerService(IUtenteService utenteService, IClienteService clienteService, IComuneIstatService comuneIstatService, IDestinazioneService destinazioneService, IEventoService eventoService, IInvitoEventoService invitoEventoService, IIscrizioneEventoService iscrizioneEventoService, IReferenteService referenteService, ITipologiaClienteService tipologiaClienteService, IFeatureService featureService, IPermissionService permissionService, IRuoloService ruoloService, ISezioneService sezioneService) { UtenteService = utenteService; ClienteService = clienteService; + ComuneIstatService = comuneIstatService; DestinazioneService = destinazioneService; EventoService = eventoService; InvitoEventoService = invitoEventoService; @@ -34,4 +35,5 @@ public class ManagerService : IManagerService public IRuoloService RuoloService { get; set; } public ISezioneService SezioneService { get; set; } public ITipologiaClienteService TipologiaClienteService { get; set; } + public IComuneIstatService ComuneIstatService { get; set; } } \ No newline at end of file diff --git a/StandManager/Components/Pages/Management/Cliente_Destinazione.razor b/StandManager/Components/Pages/Management/Cliente_Destinazione.razor index 9707047..e9c4f85 100644 --- a/StandManager/Components/Pages/Management/Cliente_Destinazione.razor +++ b/StandManager/Components/Pages/Management/Cliente_Destinazione.razor @@ -57,7 +57,7 @@
Agente - +
@@ -79,6 +79,8 @@ @code { [Parameter] public Guid destinazioneId { get; set; } = Guid.Empty; [Parameter] public Guid clienteId { get; set; } = Guid.Empty; + [Parameter] public bool canSetAgente { get; set; } = false; + [Parameter] public Guid capoareaId { get; set; } = Guid.Empty; private DestinazioneViewModel destinazione { get; set; } = new(); private IEnumerable agenti { get; set; } = new List(); @@ -91,8 +93,8 @@ protected override async Task OnInitializedAsync() { base.OnInitializedAsync(); - - 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 && !x.IsCapoarea && x.CapoareaId == capoareaId, ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome))) .Select(x => (UtenteViewModel)x).ToList(); destinazione = destinazioneId == Guid.Empty ? new() : await _managerService.DestinazioneService.RicercaPer(x => x.Id == destinazioneId, diff --git a/StandManager/Components/Pages/Management/Clienti.razor b/StandManager/Components/Pages/Management/Clienti.razor index 4e600c6..307b931 100644 --- a/StandManager/Components/Pages/Management/Clienti.razor +++ b/StandManager/Components/Pages/Management/Clienti.razor @@ -25,6 +25,8 @@
+ + Nuovo cliente @@ -122,4 +124,25 @@ await _dialogService.Alert("Si è verificato un errore durante l'importazione del file.", "Errore"); } } + + private async Task onUploadComuni(UploadChangeEventArgs args) + { + var file = args.Files.FirstOrDefault(); + if (file == null || + !file.Name.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase)) + { + await _dialogService.Alert("Sono supportati solo file Excel .xlsx", "Errore"); + return; + } + try + { + // await using var uploadStream = file.OpenReadStream(10_000_000); + await _dialogService.OpenAsync("Importazione comuni", new Dictionary() { { "args", args } }); + } + catch (Exception ex) + { + var er = ex.Message; + await _dialogService.Alert("Si è verificato un errore durante l'importazione del file.", "Errore"); + } + } } diff --git a/StandManager/Components/Pages/Management/Clienti_Edit.razor b/StandManager/Components/Pages/Management/Clienti_Edit.razor index 453a3d1..9154f42 100644 --- a/StandManager/Components/Pages/Management/Clienti_Edit.razor +++ b/StandManager/Components/Pages/Management/Clienti_Edit.razor @@ -64,31 +64,13 @@
-
- Cap - -
- -
- Citta - -
- -
- Indirizzo - -
-
Email di invito
-
- -
- Agente - + Tipologia Gestionale +
Tipologia @@ -98,9 +80,16 @@ Stato
+
+ +
- Tipologia Gestionale - + Agente + +
+
+ Capoarea +
@@ -179,10 +168,14 @@ private ClienteViewModel cliente { get; set; } = new(); private IEnumerable agenti { get; set; } = new List(); + private IEnumerable capiarea { get; set; } = new List(); private List tipologiaCliente { get; set; } = new(); private List> statoCliente { get; set; } = new(); RadzenDataGrid destinazioniGrid; + private bool isAdmin { get; set; } = false; + private Guid capoareaId { get; set; } = Guid.Empty; + private string pageTitle => cliente?.Id == Guid.Empty ? "Nuovo cliente" : "Modifica cliente"; private DialogOptions editNewDialogOption { get; set; } = new() @@ -205,23 +198,34 @@ x => x.Id == idRuolo && x.Permessi.Any(y => y.Feature.Type == FeatureType.Capoarea || y.Feature.Type == FeatureType.AdminGlobal), includi:x => x.Include(y => y.Permessi).ThenInclude(z => z.Feature)); - var isAdmin = ruolo?.Permessi.Where(x => x.Eliminato == false)?.Any(x => x.Feature.Type == FeatureType.AdminGlobal) ?? false; - agenti = ruolo == null - ? [await _managerService.UtenteService.RicercaPer(x => x.Id == idClaim)] - : (await _managerService.UtenteService.RicercaQueryable( - x => x.Eliminato == false && (isAdmin || x.CapoareaId == idClaim), + isAdmin = ruolo?.Permessi.Where(x => x.Eliminato == false)?.Any(x => x.Feature.Type == FeatureType.AdminGlobal) ?? false; + + if (ClienteId.GetValueOrDefault() != Guid.Empty) + cliente = await _managerService.ClienteService.RicercaPer(x => x.Id == ClienteId, includi: x => x.Include(y => y.Agente).Include(y => y.Capoarea).Include(y => y.TipologiaCliente).Include(y => y.Destinazioni).ThenInclude(z => z.Agente)); + else + cliente = new ClienteViewModel(); + + capoareaId = cliente.CapoareaId.GetValueOrDefault(); + + capiarea = isAdmin + ? (await _managerService.UtenteService.RicercaQueryable( + x => x.Eliminato == false && x.IsCapoarea, + ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome))) + .Select(x => (UtenteViewModel)x).ToList() + : [await _managerService.UtenteService.RicercaPer(x => x.Id == cliente.CapoareaId)]; + + agenti = cliente.CapoareaId == idClaim || isAdmin + ? (await _managerService.UtenteService.RicercaQueryable( + x => x.Eliminato == false && (isAdmin || x.CapoareaId == idClaim) && !x.IsCapoarea && x.CapoareaId == cliente.CapoareaId, includi: x => x.Include(y => y.Capoarea), ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome))) - .Select(x => (UtenteViewModel)x).ToList(); + .Select(x => (UtenteViewModel)x).ToList() + : [await _managerService.UtenteService.RicercaPer(x => x.Id == cliente.AgenteId)]; + var eUtils = new EnumUtils(); tipologiaCliente = (await _managerService.TipologiaClienteService.RicercaQueryable(ordinamento: x => x.OrderBy(y => y.Nome))).Select(x => (TipologiaClienteViewModel)x).ToList(); statoCliente = eUtils.GetEnumList(); - if (ClienteId.GetValueOrDefault() != Guid.Empty) - 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 - cliente = new ClienteViewModel(); - _dialogService.OnClose += onDialogClose; } @@ -279,7 +283,7 @@ /// private async Task EditDestinazione(DestinazioneViewModel destinazione) { - await _dialogService.OpenAsync($"Destinazione {destinazione.RagioneSociale}", new Dictionary() { { "destinazioneId", destinazione.Id }, { "clienteId", cliente.Id } }, editNewDialogOption); + await _dialogService.OpenAsync($"Destinazione {destinazione.RagioneSociale}", new Dictionary() { { "destinazioneId", destinazione.Id }, { "clienteId", cliente.Id }, { "canSetAgente", (cliente.CapoareaId == idClaim) || isAdmin }, { "capoareaId", capoareaId } }, editNewDialogOption); } /// @@ -287,7 +291,7 @@ /// private async Task onNuovaDestinazionePressed() { - await _dialogService.OpenAsync($"Nuova destinazione", new Dictionary() { { "clienteId", cliente.Id } }, editNewDialogOption); + await _dialogService.OpenAsync($"Nuova destinazione", new Dictionary() { { "clienteId", cliente.Id }, { "canSetAgente", (cliente.CapoareaId == idClaim) || isAdmin }, { "capoareaId", capoareaId } }, editNewDialogOption); } /// @@ -305,4 +309,26 @@ .Select(x => (DestinazioneViewModel)x).ToList(); } } + + /// + /// Aggiorna la drop di agenti in base al valore di capoarea + /// + private async Task OnCapoareaChange(object value) + { + var capoId = Guid.Empty; + + if (Guid.TryParse(value.ToString(), out capoId)) + { + capoareaId = capoId; + cliente.AgenteId = null; + + agenti = cliente.CapoareaId == idClaim || isAdmin + ? (await _managerService.UtenteService.RicercaQueryable( + x => x.Eliminato == false && (isAdmin || x.CapoareaId == idClaim) && !x.IsCapoarea && x.CapoareaId == capoareaId, + includi: x => x.Include(y => y.Capoarea), + ordinamento: x => x.OrderBy(y => y.Cognome).ThenBy(z => z.Nome))) + .Select(x => (UtenteViewModel)x).ToList() + : [await _managerService.UtenteService.RicercaPer(x => x.Id == cliente.AgenteId)]; + } + } } diff --git a/StandManager/Components/Pages/Management/Clienti_Import.razor b/StandManager/Components/Pages/Management/Clienti_Import.razor index e6881b4..f3af828 100644 --- a/StandManager/Components/Pages/Management/Clienti_Import.razor +++ b/StandManager/Components/Pages/Management/Clienti_Import.razor @@ -41,24 +41,22 @@ var codiciAgente = rows.Select(r => new { CodiceAgente = r.Agente, Nome = r.DescrizioneAgente, Capoarea = r.CapoArea }).Distinct().ToList(); var codiciCapoarea = rows.Select(r => new { CodiceCapoarea = r.CapoArea, Nome = r.DescrizioneCapoArea }).Distinct().ToList(); - var capoareaList = await _managerService.UtenteService.ListaCapoarea(); foreach (var fileCapoarea in codiciCapoarea) { - var capoarea = await _managerService.UtenteService.RicercaPer(x => x.CodiceAgente == fileCapoarea.CodiceCapoarea); - if ((capoarea?.Id ?? new Guid()) != Guid.Empty) - continue; - capoarea = await mapCapoArea(new Utente(), fileCapoarea.CodiceCapoarea, fileCapoarea.Nome); + var capoarea = await _managerService.UtenteService.RicercaPer(x => x.CodiceAgente == fileCapoarea.CodiceCapoarea, solaLettura: false); + + capoarea = await mapCapoArea(capoarea ?? new Utente(), fileCapoarea.CodiceCapoarea, fileCapoarea.Nome); await _managerService.UtenteService.Salva(capoarea, idClaim); - capoareaList.Add(capoarea); } - + + var capoareaList = await _managerService.UtenteService.ListaCapoarea(); foreach (var fileAgente in codiciAgente) { - var agente = await _managerService.UtenteService.RicercaPer(x => x.CodiceAgente == fileAgente.CodiceAgente); - if ((agente?.Id ?? new Guid()) != Guid.Empty) - continue; + var agente = await _managerService.UtenteService.RicercaPer(x => x.CodiceAgente == fileAgente.CodiceAgente, solaLettura: false); + // if ((agente?.Id ?? new Guid()) != Guid.Empty) + // continue; var capoarea = capoareaList.FirstOrDefault(x => x.CodiceAgente == fileAgente.Capoarea); - agente = await mapAgente(new Utente(), fileAgente.CodiceAgente, fileAgente.Nome, capoarea.Id); + agente = await mapAgente(agente ?? new Utente(), fileAgente.CodiceAgente, fileAgente.Nome, capoarea?.Id); await _managerService.UtenteService.Salva(agente, idClaim); } @@ -95,15 +93,9 @@ model.Rid = firstRow.CodCli; model.RagioneSociale = firstRow.RagSocCliente; model.PartitaIva = firstRow.PartitaIva; - - /*var agente = await _managerService.UtenteService.RicercaPer(filtro: x => x.CodiceAgente == firstRow.Agente && x.Eliminato == false, solaLettura: false) ?? new Utente(); - agente = await mapAgente(agente, firstRow, model.CapoareaId); - if (agente.Id == Guid.Empty) agente.Password = ""; - var savedAgente = await _managerService.UtenteService.Salva(agente, idClaim); - model.AgenteId = savedAgente.Id;*/ - - // TODO: Problema nel salvataggio delle destinazioni + // TODO: TipologiaCliente da inserire (pesco a db) model.Destinazioni ??= new(); + foreach (var destinazioneRiga in rows) { var destinazione = model.Destinazioni.FirstOrDefault(x => x.Rid == destinazioneRiga.CodDes) ?? new Destinazione(); @@ -117,6 +109,8 @@ private async Task mapDestinazione(Destinazione model, Guid clienteId, ClienteExcelViewModel row, Guid? agenteId) { + + // TODO: Comune da inserire (pesco a db) model.Rid = row.CodDes; model.RagioneSociale = row.RagSocDestinazione; model.PartitaIva = row.PartitaIva; @@ -150,10 +144,10 @@ model.Username = nome; model.CodiceAgente = codice; model.Nome = nome; - model.Cognome = ""; - model.Email = ""; + model.Cognome = string.Empty; + model.Email = string.Empty; model.Password = string.Empty; - /*model.CapoareaId = capoareaId;*/ + model.CapoareaId = capoareaId; return model; } diff --git a/StandManager/Components/Pages/Management/Comuni_Import.razor b/StandManager/Components/Pages/Management/Comuni_Import.razor new file mode 100644 index 0000000..d854c39 --- /dev/null +++ b/StandManager/Components/Pages/Management/Comuni_Import.razor @@ -0,0 +1,73 @@ +@using ClosedXML.Excel +@using Microsoft.EntityFrameworkCore +@using StandManager.Model +@attribute [Authorize] + +@rendermode InteractiveServer + +@inject AuthenticationStateProvider auth + + + + + +@code { + [CascadingParameter] private Dialog _dialog { get; set; } + [Parameter] public UploadChangeEventArgs args { get; set; } + + private int comuniTotali { get; set; } = 0; + private int counter { get; set; } = 0; + private string counterLabel { get; set; } = string.Empty; + + protected override async Task OnInitializedAsync() + { + base.OnInitializedAsync(); + var file = args.Files.FirstOrDefault(); + await using var uploadStream = file.OpenReadStream(10_000_000); + var idClaim = await MembershipUtils.GetUserId(auth); + + 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 rows = new List(usedRange.RowCount() - 1); + + foreach (var row in usedRange.RowsUsed().Skip(1)) + rows.Add(new ComuneIstatExcelViewModel(row)); + + + var comuni = rows.ToList(); + comuniTotali = comuni.Count; + counterLabel = " di " + comuniTotali; + + foreach (var comune in comuni) + { + var comuneDb = await _managerService.ComuneIstatService.RicercaPer( + x => x.Istat == comune.Istat && x.Eliminato == false, + solaLettura: false) ?? new ComuneIstat(); + + comuneDb = await mapComune(comuneDb, comune); + await _managerService.ComuneIstatService.Salva(comuneDb, idClaim); + counter += 1; + StateHasChanged(); + } + + ms.Close(); + _dialogService.Close(); + } + + private async Task mapComune(ComuneIstat model, ComuneIstatExcelViewModel row) + { + model.Istat = row.Istat; + model.Comune = row.Comune; + model.Regione = row.Regione; + model.Provincia = row.Provincia; + model.Prefisso = row.Prefisso; + model.CodFisco = row.CodFisco; + + return model; + } +} diff --git a/StandManager/Model/ClienteViewModel.cs b/StandManager/Model/ClienteViewModel.cs index ad1b03d..7ad61f7 100644 --- a/StandManager/Model/ClienteViewModel.cs +++ b/StandManager/Model/ClienteViewModel.cs @@ -20,6 +20,8 @@ public class ClienteViewModel public string NomeCapoarea { get; set; } public Guid? AgenteId { get; set; } public UtenteViewModel Agente { get; set; } + public Guid? CapoareaId { get; set; } + public UtenteViewModel Capoarea { get; set; } public List Destinazioni { get; set; } public string Rid { get; set; } @@ -39,6 +41,8 @@ public class ClienteViewModel NomeCapoarea = model.Capoarea?.Nome.ToString(), Agente = model.Agente, AgenteId = model.AgenteId, + Capoarea = model.Capoarea, + CapoareaId = model.CapoareaId, Cap = model.Cap, Citta = model.Citta, Email = model.Email, diff --git a/StandManager/Model/ComuneIstatExcelViewModel.cs b/StandManager/Model/ComuneIstatExcelViewModel.cs new file mode 100644 index 0000000..bbc6ee9 --- /dev/null +++ b/StandManager/Model/ComuneIstatExcelViewModel.cs @@ -0,0 +1,24 @@ +using ClosedXML.Excel; + +namespace StandManager.Model; + +public class ComuneIstatExcelViewModel +{ + public ComuneIstatExcelViewModel(IXLRangeRow row) + { + Istat = row.Cell(1).GetString(); + Comune = row.Cell(2).GetString(); + Regione = row.Cell(3).GetString(); + Provincia = row.Cell(4).GetString(); + Prefisso = row.Cell(5).GetString(); + CodFisco = row.Cell(6).GetString(); + } + + public string Istat { get; set; } + public string Comune { get; set; } + public string Regione { get; set; } + public string Provincia { get; set; } + public string Prefisso { get; set; } + public string CodFisco { get; set; } + +}