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; 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) public async Task<List<ActivityDTO>> GetActivity(Expression<Func<StbActivity, bool>>? whereCond = null)
{ {
var activities = await localDb.Get(whereCond); 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.Copy;
using salesbook.Shared.Core.Messages.Activity.New; using salesbook.Shared.Core.Messages.Activity.New;
using salesbook.Shared.Core.Messages.Back; using salesbook.Shared.Core.Messages.Back;
using salesbook.Shared.Core.Messages.Contact;
using salesbook.Shared.Core.Services; using salesbook.Shared.Core.Services;
namespace salesbook.Maui namespace salesbook.Maui
@@ -61,6 +62,7 @@ namespace salesbook.Maui
builder.Services.AddScoped<NewActivityService>(); builder.Services.AddScoped<NewActivityService>();
builder.Services.AddScoped<BackNavigationService>(); builder.Services.AddScoped<BackNavigationService>();
builder.Services.AddScoped<CopyActivityService>(); builder.Services.AddScoped<CopyActivityService>();
builder.Services.AddScoped<NewContactService>();
#if DEBUG #if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools(); builder.Services.AddBlazorWebViewDeveloperTools();

View File

@@ -3,6 +3,7 @@
@using salesbook.Shared.Core.Entity @using salesbook.Shared.Core.Entity
@using salesbook.Shared.Core.Messages.Activity.Copy @using salesbook.Shared.Core.Messages.Activity.Copy
@using salesbook.Shared.Core.Messages.Activity.New @using salesbook.Shared.Core.Messages.Activity.New
@using salesbook.Shared.Core.Messages.Contact
@inject IDialogService Dialog @inject IDialogService Dialog
@inject IMessenger Messenger @inject IMessenger Messenger
@inject CopyActivityService CopyActivityService @inject CopyActivityService CopyActivityService
@@ -96,6 +97,10 @@
private async Task CreateUser() private async Task CreateUser()
{ {
var result = await ModalHelpers.OpenUserForm(Dialog, null); 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.SingleElements
@using salesbook.Shared.Components.Layout.Spinner @using salesbook.Shared.Components.Layout.Spinner
@using salesbook.Shared.Components.SingleElements.BottomSheet @using salesbook.Shared.Components.SingleElements.BottomSheet
@using salesbook.Shared.Core.Entity
@using salesbook.Shared.Core.Messages.Activity.New @using salesbook.Shared.Core.Messages.Activity.New
@inject IManageDataService ManageData @inject IManageDataService ManageData
@inject IJSRuntime JS @inject IJSRuntime JS

View File

@@ -10,6 +10,7 @@
@inject IManageDataService ManageData @inject IManageDataService ManageData
@inject IMapper Mapper @inject IMapper Mapper
@inject IDialogService Dialog @inject IDialogService Dialog
@inject INetworkService NetworkService
<HeaderLayout BackTo="Indietro" LabelSave="Modifica" OnSave="() => OpenUserForm(Anag)" Back="true" BackOnTop="true" Title="" ShowProfile="false" /> <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.Layout.Spinner
@using salesbook.Shared.Components.SingleElements @using salesbook.Shared.Components.SingleElements
@using salesbook.Shared.Core.Entity @using salesbook.Shared.Core.Entity
@using salesbook.Shared.Core.Messages.Contact
@inject IManageDataService ManageData @inject IManageDataService ManageData
@inject NewContactService NewContact
<HeaderLayout Title="Contatti"/> <HeaderLayout Title="Contatti"/>
@@ -65,6 +67,11 @@
private FilterUserDTO Filter { get; set; } = new(); private FilterUserDTO Filter { get; set; } = new();
private string TypeUser { get; set; } = "all"; private string TypeUser { get; set; } = "all";
protected override void OnInitialized()
{
NewContact.OnContactCreated += async activityId => await OnActivityCreated(activityId);
}
protected override async Task OnAfterRenderAsync(bool firstRender) protected override async Task OnAfterRenderAsync(bool firstRender)
{ {
if (firstRender) if (firstRender)
@@ -186,6 +193,91 @@
FilteredGroupedUserList = result; 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() private void ToggleFilter()
{ {
OpenFilter = !OpenFilter; OpenFilter = !OpenFilter;

View File

@@ -102,9 +102,15 @@
@if (!IsView) @if (!IsView)
{ {
<div class="search-address" @onclick="() => OpenSearchAddress = !OpenSearchAddress"> <div class="container-button mb-3">
<span>Cerca indirizzo</span> <MudButton Class="button-settings blue-icon"
<MudIcon Size="Size.Small" Icon="@Icons.Material.Rounded.Search"/> FullWidth="true"
StartIcon="@Icons.Material.Rounded.Search"
Size="Size.Medium"
OnClick="() => OpenSearchAddress = !OpenSearchAddress"
Variant="Variant.Outlined">
Cerca indirizzo
</MudButton>
</div> </div>
} }
@@ -242,8 +248,11 @@
} }
} }
</div> </div>
}
<div class="container-button"> <div class="container-button">
@if (IsNew)
{
<MudButton Class="button-settings gray-icon" <MudButton Class="button-settings gray-icon"
FullWidth="true" FullWidth="true"
StartIcon="@Icons.Material.Filled.PersonAddAlt1" StartIcon="@Icons.Material.Filled.PersonAddAlt1"
@@ -252,8 +261,22 @@
Variant="Variant.Outlined"> Variant="Variant.Outlined">
Persona di riferimento Persona di riferimento
</MudButton> </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> </div>
<MudMessageBox MarkupMessage="new MarkupString(VatMessage)" @ref="CheckVat" Class="c-messageBox" Title="Verifica partita iva" CancelText="@(VatAlreadyRegistered ? "" : "Annulla")"> <MudMessageBox MarkupMessage="new MarkupString(VatMessage)" @ref="CheckVat" Class="c-messageBox" Title="Verifica partita iva" CancelText="@(VatAlreadyRegistered ? "" : "Annulla")">
@@ -330,14 +353,32 @@
PersRif = PersRifList 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; SuccessAnimation = true;
StateHasChanged(); StateHasChanged();
await Task.Delay(1250); await Task.Delay(1250);
MudDialog.Close(); MudDialog.Close(response);
} }
private async Task LoadData() private async Task LoadData()
@@ -492,4 +533,9 @@
ContactModel.Prov = Address.Prov; ContactModel.Prov = Address.Prov;
ContactModel.Cap = Address.Cap; 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 public class AnagClie
{ {
[PrimaryKey, Column("cod_anag"), JsonPropertyName("codAnag")] [PrimaryKey, Column("cod_anag"), JsonPropertyName("codAnag")]
public string CodAnag { get; set; } public string? CodAnag { get; set; }
[Column("cod_vtip"), JsonPropertyName("codVtip")] [Column("cod_vtip"), JsonPropertyName("codVtip")]
public string? CodVtip { get; set; } public string? CodVtip { get; set; }

View File

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

View File

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

View File

@@ -10,6 +10,7 @@ public interface IManageDataService
Task<List<ActivityDTO>> GetActivity(Expression<Func<StbActivity, bool>>? whereCond = null); Task<List<ActivityDTO>> GetActivity(Expression<Func<StbActivity, bool>>? whereCond = null);
Task<List<ContactDTO>> GetContact(); Task<List<ContactDTO>> GetContact();
Task<ContactDTO?> GetSpecificContact(string codAnag, bool IsContact);
Task InsertOrUpdate<T>(T objectToSave); 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) => public Task<List<StbActivity>?> SaveActivity(ActivityDTO activity) =>
integryApiRestClient.AuthorizedPost<List<StbActivity>?>("crm/saveActivity", activity); integryApiRestClient.AuthorizedPost<List<StbActivity>?>("crm/saveActivity", activity);
public Task SaveContact(CRMCreateContactRequestDTO request) => public Task<CRMCreateContactResponseDTO?> SaveContact(CRMCreateContactRequestDTO request) =>
integryApiRestClient.AuthorizedPost<object>("crm/createContact", request); integryApiRestClient.AuthorizedPost<CRMCreateContactResponseDTO>("crm/createContact", request);
public Task<CheckVatResponseDTO> CheckVat(CheckVatRequestDTO request) => public Task<CheckVatResponseDTO> CheckVat(CheckVatRequestDTO request) =>
integryApiRestClient.Post<CheckVatResponseDTO>("checkPartitaIva", request)!; integryApiRestClient.Post<CheckVatResponseDTO>("checkPartitaIva", request)!;

View File

@@ -123,6 +123,12 @@
color: var(--mud-palette-dark); 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 { .container-button .button-settings.green-icon .mud-icon-root {
border: 1px solid hsl(from var(--mud-palette-success-lighten) h s 95%); border: 1px solid hsl(from var(--mud-palette-success-lighten) h s 95%);
background: 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(); throw new NotImplementedException();
} }
public Task<ContactDTO> GetSpecificContact(string codAnag, bool IsContact)
{
throw new NotImplementedException();
}
public Task InsertOrUpdate<T>(T objectToSave) public Task InsertOrUpdate<T>(T objectToSave)
{ {
throw new NotImplementedException(); throw new NotImplementedException();