Gestito aggiornamento elenco contatti in caso di aggiunta o modifica del prospect / cliente

This commit is contained in:
2025-07-25 14:52:00 +02:00
parent 9c69884cc9
commit 8ebc6e3b8f
17 changed files with 229 additions and 20 deletions

View File

@@ -28,6 +28,22 @@ public class ManageDataService(LocalDbService localDb, IMapper mapper) : IManage
return contactMapper;
}
public async Task<ContactDTO?> GetSpecificContact(string codAnag, bool isContact)
{
if (isContact)
{
var contact = (await localDb.Get<AnagClie>(x => x.CodAnag != null && x.CodAnag.Equals(codAnag))).LastOrDefault();
return contact == null ? null : mapper.Map<ContactDTO>(contact);
}
else
{
var contact = (await localDb.Get<PtbPros>(x => x.CodPpro != null && x.CodPpro.Equals(codAnag))).LastOrDefault();
return contact == null ? null : mapper.Map<ContactDTO>(contact);
}
}
public async Task<List<ActivityDTO>> GetActivity(Expression<Func<StbActivity, bool>>? whereCond = null)
{
var activities = await localDb.Get(whereCond);

View File

@@ -13,6 +13,7 @@ using salesbook.Shared.Core.Interface;
using salesbook.Shared.Core.Messages.Activity.Copy;
using salesbook.Shared.Core.Messages.Activity.New;
using salesbook.Shared.Core.Messages.Back;
using salesbook.Shared.Core.Messages.Contact;
using salesbook.Shared.Core.Services;
namespace salesbook.Maui
@@ -61,6 +62,7 @@ namespace salesbook.Maui
builder.Services.AddScoped<NewActivityService>();
builder.Services.AddScoped<BackNavigationService>();
builder.Services.AddScoped<CopyActivityService>();
builder.Services.AddScoped<NewContactService>();
#if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools();

View File

@@ -3,12 +3,13 @@
@using salesbook.Shared.Core.Entity
@using salesbook.Shared.Core.Messages.Activity.Copy
@using salesbook.Shared.Core.Messages.Activity.New
@using salesbook.Shared.Core.Messages.Contact
@inject IDialogService Dialog
@inject IMessenger Messenger
@inject CopyActivityService CopyActivityService
<div class="container animated-navbar @(IsVisible ? "show-nav" : "hide-nav") @(IsVisible? PlusVisible ? "with-plus" : "without-plus" : "with-plus")">
<nav class="navbar @(IsVisible? PlusVisible ? "with-plus" : "without-plus" : "with-plus")">
<div class="container animated-navbar @(IsVisible ? "show-nav" : "hide-nav") @(IsVisible ? PlusVisible ? "with-plus" : "without-plus" : "with-plus")">
<nav class="navbar @(IsVisible ? PlusVisible ? "with-plus" : "without-plus" : "with-plus")">
<div class="container-navbar">
<ul class="navbar-nav flex-row nav-justified align-items-center w-100 text-center">
<li class="nav-item">
@@ -42,7 +43,7 @@
{
<MudMenu PopoverClass="custom_popover" AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomRight">
<ActivatorContent>
<MudFab Class="custom-plus-button" Color="Color.Surface" Size="Size.Medium" IconSize="Size.Medium" IconColor="Color.Primary" StartIcon="@Icons.Material.Filled.Add" />
<MudFab Class="custom-plus-button" Color="Color.Surface" Size="Size.Medium" IconSize="Size.Medium" IconColor="Color.Primary" StartIcon="@Icons.Material.Filled.Add"/>
</ActivatorContent>
<ChildContent>
<MudMenuItem OnClick="() => CreateUser()">Nuovo contatto</MudMenuItem>
@@ -96,6 +97,10 @@
private async Task CreateUser()
{
var result = await ModalHelpers.OpenUserForm(Dialog, null);
if (result is { Canceled: false, Data: not null } && result.Data.GetType() == typeof(CRMCreateContactResponseDTO))
{
Messenger.Send(new NewContactMessage((CRMCreateContactResponseDTO)result.Data));
}
}
}

View File

@@ -5,7 +5,6 @@
@using salesbook.Shared.Components.SingleElements
@using salesbook.Shared.Components.Layout.Spinner
@using salesbook.Shared.Components.SingleElements.BottomSheet
@using salesbook.Shared.Core.Entity
@using salesbook.Shared.Core.Messages.Activity.New
@inject IManageDataService ManageData
@inject IJSRuntime JS

View File

@@ -10,6 +10,7 @@
@inject IManageDataService ManageData
@inject IMapper Mapper
@inject IDialogService Dialog
@inject INetworkService NetworkService
<HeaderLayout BackTo="Indietro" LabelSave="Modifica" OnSave="() => OpenUserForm(Anag)" Back="true" BackOnTop="true" Title="" ShowProfile="false" />

View File

@@ -7,7 +7,9 @@
@using salesbook.Shared.Components.Layout.Spinner
@using salesbook.Shared.Components.SingleElements
@using salesbook.Shared.Core.Entity
@using salesbook.Shared.Core.Messages.Contact
@inject IManageDataService ManageData
@inject NewContactService NewContact
<HeaderLayout Title="Contatti"/>
@@ -65,6 +67,11 @@
private FilterUserDTO Filter { get; set; } = new();
private string TypeUser { get; set; } = "all";
protected override void OnInitialized()
{
NewContact.OnContactCreated += async activityId => await OnActivityCreated(activityId);
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
@@ -186,6 +193,91 @@
FilteredGroupedUserList = result;
}
private async Task OnActivityCreated(CRMCreateContactResponseDTO response)
{
IsLoading = true;
string codAnag;
bool isContact;
switch (response)
{
case null:
return;
case { AnagClie: null, PtbPros: not null }:
await ManageData.InsertOrUpdate(response.PtbPros);
isContact = false;
codAnag = response.PtbPros.CodPpro!;
break;
case { AnagClie: not null, PtbPros: null }:
await ManageData.InsertOrUpdate(response.AnagClie);
isContact = true;
codAnag = response.AnagClie.CodAnag!;
break;
default:
return;
}
var contact = await ManageData.GetSpecificContact(codAnag, isContact);
if (contact == null)
{
IsLoading = false;
return;
}
var firstChar = char.ToUpper(contact.RagSoc![0]);
var currentLetter = char.IsLetter(firstChar) ? firstChar.ToString() : "#";
var insertIndex = -1;
var foundHeader = false;
for (var i = 0; i < GroupedUserList.Count; i++)
{
var current = GroupedUserList[i];
if (!current.ShowHeader || current.HeaderLetter != currentLetter) continue;
foundHeader = true;
insertIndex = i + 1;
while (insertIndex < GroupedUserList.Count &&
GroupedUserList[insertIndex].HeaderLetter == currentLetter &&
string.Compare(contact.RagSoc, GroupedUserList[insertIndex].User.RagSoc, StringComparison.OrdinalIgnoreCase) > 0)
{
insertIndex++;
}
break;
}
if (!foundHeader)
{
var headerItem = new UserDisplayItem
{
HeaderLetter = currentLetter,
ShowHeader = true,
User = contact
};
GroupedUserList.Add(headerItem);
}
else
{
var newItem = new UserDisplayItem
{
HeaderLetter = currentLetter,
ShowHeader = false,
User = contact
};
GroupedUserList.Insert(insertIndex, newItem);
}
FilterUsers();
IsLoading = false;
}
private void ToggleFilter()
{
OpenFilter = !OpenFilter;

View File

@@ -102,9 +102,15 @@
@if (!IsView)
{
<div class="search-address" @onclick="() => OpenSearchAddress = !OpenSearchAddress">
<span>Cerca indirizzo</span>
<MudIcon Size="Size.Small" Icon="@Icons.Material.Rounded.Search"/>
<div class="container-button mb-3">
<MudButton Class="button-settings blue-icon"
FullWidth="true"
StartIcon="@Icons.Material.Rounded.Search"
Size="Size.Medium"
OnClick="() => OpenSearchAddress = !OpenSearchAddress"
Variant="Variant.Outlined">
Cerca indirizzo
</MudButton>
</div>
}
@@ -242,8 +248,11 @@
}
}
</div>
}
<div class="container-button">
<div class="container-button">
@if (IsNew)
{
<MudButton Class="button-settings gray-icon"
FullWidth="true"
StartIcon="@Icons.Material.Filled.PersonAddAlt1"
@@ -252,8 +261,22 @@
Variant="Variant.Outlined">
Persona di riferimento
</MudButton>
</div>
}
}
else
{
@if (NetworkService.IsNetworkAvailable() && !ContactModel.IsContact)
{
<MudButton Class="button-settings blue-icon"
FullWidth="true"
StartIcon="@Icons.Material.Rounded.Sync"
Size="Size.Medium"
OnClick="ConvertProspectToContact"
Variant="Variant.Outlined">
Converti in cliente
</MudButton>
}
}
</div>
</div>
<MudMessageBox MarkupMessage="new MarkupString(VatMessage)" @ref="CheckVat" Class="c-messageBox" Title="Verifica partita iva" CancelText="@(VatAlreadyRegistered ? "" : "Annulla")">
@@ -330,14 +353,32 @@
PersRif = PersRifList
};
await IntegryApiService.SaveContact(requestDto);
var response = await IntegryApiService.SaveContact(requestDto);
switch (response)
{
case null:
VisibleOverlay = false;
StateHasChanged();
return;
case {AnagClie: null, PtbPros: not null}:
await ManageData.InsertOrUpdate(response.PtbPros);
break;
case { AnagClie: not null, PtbPros: null }:
await ManageData.InsertOrUpdate(response.AnagClie);
break;
default:
VisibleOverlay = false;
StateHasChanged();
return;
}
SuccessAnimation = true;
StateHasChanged();
await Task.Delay(1250);
MudDialog.Close();
MudDialog.Close(response);
}
private async Task LoadData()
@@ -492,4 +533,9 @@
ContactModel.Prov = Address.Prov;
ContactModel.Cap = Address.Cap;
}
private async Task ConvertProspectToContact()
{
}
}

View File

@@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
using salesbook.Shared.Core.Entity;
namespace salesbook.Shared.Core.Dto;
public class CRMCreateContactResponseDTO
{
[JsonPropertyName("anagClie")]
public AnagClie? AnagClie { get; set; }
[JsonPropertyName("ptbPros")]
public PtbPros? PtbPros { get; set; }
}

View File

@@ -7,7 +7,7 @@ namespace salesbook.Shared.Core.Entity;
public class AnagClie
{
[PrimaryKey, Column("cod_anag"), JsonPropertyName("codAnag")]
public string CodAnag { get; set; }
public string? CodAnag { get; set; }
[Column("cod_vtip"), JsonPropertyName("codVtip")]
public string? CodVtip { get; set; }

View File

@@ -7,7 +7,7 @@ namespace salesbook.Shared.Core.Entity;
public class PtbPros
{
[PrimaryKey, Column("cod_ppro"), JsonPropertyName("codPpro")]
public string CodPpro { get; set; }
public string? CodPpro { get; set; }
[Column("agenzia_banca"), JsonPropertyName("agenziaBanca")]
public string AgenziaBanca { get; set; }

View File

@@ -14,7 +14,7 @@ public interface IIntegryApiService
Task DeleteActivity(string activityId);
Task<List<StbActivity>?> SaveActivity(ActivityDTO activity);
Task SaveContact(CRMCreateContactRequestDTO request);
Task<CRMCreateContactResponseDTO?> SaveContact(CRMCreateContactRequestDTO request);
Task<CheckVatResponseDTO> CheckVat(CheckVatRequestDTO request);
//Google

View File

@@ -10,6 +10,7 @@ public interface IManageDataService
Task<List<ActivityDTO>> GetActivity(Expression<Func<StbActivity, bool>>? whereCond = null);
Task<List<ContactDTO>> GetContact();
Task<ContactDTO?> GetSpecificContact(string codAnag, bool IsContact);
Task InsertOrUpdate<T>(T objectToSave);

View File

@@ -0,0 +1,6 @@
using CommunityToolkit.Mvvm.Messaging.Messages;
using salesbook.Shared.Core.Dto;
namespace salesbook.Shared.Core.Messages.Contact;
public class NewContactMessage(CRMCreateContactResponseDTO value) : ValueChangedMessage<CRMCreateContactResponseDTO>(value);

View File

@@ -0,0 +1,17 @@
using CommunityToolkit.Mvvm.Messaging;
using salesbook.Shared.Core.Dto;
namespace salesbook.Shared.Core.Messages.Contact;
public class NewContactService
{
public event Action<CRMCreateContactResponseDTO>? OnContactCreated;
public NewContactService(IMessenger messenger)
{
messenger.Register<NewContactMessage>(this, (_, o) =>
{
OnContactCreated?.Invoke(o.Value);
});
}
}

View File

@@ -69,8 +69,8 @@ public class IntegryApiService(IIntegryApiRestClient integryApiRestClient, IUser
public Task<List<StbActivity>?> SaveActivity(ActivityDTO activity) =>
integryApiRestClient.AuthorizedPost<List<StbActivity>?>("crm/saveActivity", activity);
public Task SaveContact(CRMCreateContactRequestDTO request) =>
integryApiRestClient.AuthorizedPost<object>("crm/createContact", request);
public Task<CRMCreateContactResponseDTO?> SaveContact(CRMCreateContactRequestDTO request) =>
integryApiRestClient.AuthorizedPost<CRMCreateContactResponseDTO>("crm/createContact", request);
public Task<CheckVatResponseDTO> CheckVat(CheckVatRequestDTO request) =>
integryApiRestClient.Post<CheckVatResponseDTO>("checkPartitaIva", request)!;

View File

@@ -123,6 +123,12 @@
color: var(--mud-palette-dark);
}
.container-button .button-settings.blue-icon .mud-icon-root {
border: 1px solid var(--mud-palette-primary);
background: hsl(from var(--mud-palette-primary-lighten) h s 95%);
color: var(--mud-palette-primary-darken);
}
.container-button .button-settings.green-icon .mud-icon-root {
border: 1px solid hsl(from var(--mud-palette-success-lighten) h s 95%);
background: hsl(from var(--mud-palette-success-lighten) h s 95%);

View File

@@ -22,6 +22,11 @@ public class ManageDataService : IManageDataService
throw new NotImplementedException();
}
public Task<ContactDTO> GetSpecificContact(string codAnag, bool IsContact)
{
throw new NotImplementedException();
}
public Task InsertOrUpdate<T>(T objectToSave)
{
throw new NotImplementedException();