From 7c718360d8cb332befe65bf045a4104e7f24c8ef Mon Sep 17 00:00:00 2001 From: Frede Hundewadt Date: Thu, 17 Nov 2022 19:11:49 +0100 Subject: [PATCH] contacts display add/remove/edit --- .../Components/DisplayStateComponent.razor | 2 +- .../ICrmContactHttpRepository.cs | 6 +- .../CrmCompanyHttpRepository.cs | 15 +- .../CrmContactHttpRepository.cs | 73 +++ .../Pages/CrmCompanyContactNewPage.razor | 59 --- .../Pages/CrmCompanyContactNewPage.razor.cs | 19 - Wonky.Client/Pages/CrmCompanyNewPage.razor | 101 ++-- Wonky.Client/Pages/CrmCompanyNewPage.razor.cs | 152 +++--- Wonky.Client/Pages/CrmCompanyViewPage.razor | 432 +++++++++--------- .../Pages/CrmCompanyViewPage.razor.cs | 272 ++++++----- Wonky.Client/Program.cs | 2 + Wonky.Client/Shared/ContactModal.razor | 76 +++ Wonky.Client/Shared/ContactModal.razor.cs | 97 ++++ Wonky.Client/Wonky.Client.csproj | 8 +- Wonky.Client/wwwroot/appsettings.json | 2 +- Wonky.Entity/DTO/CompanyDto.cs | 6 +- Wonky.Entity/DTO/ContactDto.cs | 12 +- 17 files changed, 785 insertions(+), 549 deletions(-) create mode 100644 Wonky.Client/HttpRepository/CrmContactHttpRepository.cs delete mode 100644 Wonky.Client/Pages/CrmCompanyContactNewPage.razor delete mode 100644 Wonky.Client/Pages/CrmCompanyContactNewPage.razor.cs create mode 100644 Wonky.Client/Shared/ContactModal.razor create mode 100644 Wonky.Client/Shared/ContactModal.razor.cs diff --git a/Wonky.Client/Components/DisplayStateComponent.razor b/Wonky.Client/Components/DisplayStateComponent.razor index 9e859db8..2400c657 100644 --- a/Wonky.Client/Components/DisplayStateComponent.razor +++ b/Wonky.Client/Components/DisplayStateComponent.razor @@ -16,7 +16,7 @@ *@ @* state *@ -state +state @code{ [Parameter] public string StateClass { get; set; } = ""; } diff --git a/Wonky.Client/HttpInterfaces/ICrmContactHttpRepository.cs b/Wonky.Client/HttpInterfaces/ICrmContactHttpRepository.cs index 64148918..685b999f 100644 --- a/Wonky.Client/HttpInterfaces/ICrmContactHttpRepository.cs +++ b/Wonky.Client/HttpInterfaces/ICrmContactHttpRepository.cs @@ -4,5 +4,9 @@ namespace Wonky.Client.HttpInterfaces; public interface ICrmContactHttpRepository { - Task CreateContact(ContactDto contact); + Task CreateContact(ContactDto model); + Task GetContact(string companyId, string contactId); + Task> GetContacts(string companyId); + Task DeleteContact(string companyId, string contactId); + Task UpdateContact(ContactDto model); } \ No newline at end of file diff --git a/Wonky.Client/HttpRepository/CrmCompanyHttpRepository.cs b/Wonky.Client/HttpRepository/CrmCompanyHttpRepository.cs index f89bf8d5..bdd10556 100644 --- a/Wonky.Client/HttpRepository/CrmCompanyHttpRepository.cs +++ b/Wonky.Client/HttpRepository/CrmCompanyHttpRepository.cs @@ -44,7 +44,7 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository private readonly NavigationManager _navigation; private ILogger _logger; private readonly HttpClient _client; - private readonly ApiConfig _apiConfig; + private readonly ApiConfig _conf; public CrmCompanyHttpRepository(HttpClient client, ILogger logger, @@ -54,8 +54,9 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository _client = client; _logger = logger; _navigation = navigation; - _apiConfig = apiConfig.Value; + _conf = apiConfig.Value; } + /// /// Get from crm endpoint /// @@ -73,7 +74,7 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository ["isHidden"] = pagingParameters.IsHidden.ToString(), ["hasFolded"] = pagingParameters.HasFolded.ToString() }; - var response = await _client.GetAsync(QueryHelpers.AddQueryString($"{_apiConfig.CrmCustomers}/page", queryString)); + var response = await _client.GetAsync(QueryHelpers.AddQueryString($"{_conf.CrmCustomers}/page", queryString)); var content = await response.Content.ReadAsStringAsync(); @@ -87,7 +88,7 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository public async Task GetCompanyById(string companyId) { - var company = await _client.GetFromJsonAsync($"{_apiConfig.CrmCustomers}/{companyId}"); + var company = await _client.GetFromJsonAsync($"{_conf.CrmCustomers}/{companyId}"); return company ?? new CompanyDto(); } @@ -98,7 +99,7 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository /// company id public async Task CreateCompany(CompanyDto model) { - var response = await _client.PostAsJsonAsync($"{_apiConfig.CrmCustomers}", model); + var response = await _client.PostAsJsonAsync($"{_conf.CrmCustomers}", model); var content = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize(content, _options); return result.CompanyId; @@ -112,7 +113,7 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository /// public async Task UpdateCompany(string companyId, CompanyDto model) { - var response = await _client.PutAsJsonAsync($"{_apiConfig.CrmCustomers}/{companyId}", model); + var response = await _client.PutAsJsonAsync($"{_conf.CrmCustomers}/{companyId}", model); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); return response.IsSuccessStatusCode; @@ -125,7 +126,7 @@ public class CrmCompanyHttpRepository : ICrmCompanyHttpRepository /// public async Task DeleteCompany(string companyId) { - var response = await _client.DeleteAsync($"{_apiConfig.CrmCustomers}/{companyId}"); + var response = await _client.DeleteAsync($"{_conf.CrmCustomers}/{companyId}"); return response.IsSuccessStatusCode; } } \ No newline at end of file diff --git a/Wonky.Client/HttpRepository/CrmContactHttpRepository.cs b/Wonky.Client/HttpRepository/CrmContactHttpRepository.cs new file mode 100644 index 00000000..83e93730 --- /dev/null +++ b/Wonky.Client/HttpRepository/CrmContactHttpRepository.cs @@ -0,0 +1,73 @@ +using System.Net.Http.Json; +using System.Text.Json; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Options; +using Wonky.Client.HttpInterfaces; +using Wonky.Entity.Configuration; +using Wonky.Entity.DTO; + +namespace Wonky.Client.HttpRepository; + +public class CrmContactHttpRepository : ICrmContactHttpRepository +{ + private readonly JsonSerializerOptions _options = new () + { + PropertyNameCaseInsensitive = true + }; + + private readonly NavigationManager _navigation; + private ILogger _logger; + private readonly HttpClient _client; + private readonly ApiConfig _conf; + + public CrmContactHttpRepository(HttpClient client, + ILogger logger, + NavigationManager navigation, + IOptions apiConfig) + { + _client = client; + _logger = logger; + _navigation = navigation; + _conf = apiConfig.Value; + } + + /// + /// Create contact + /// + /// + public async Task CreateContact(ContactDto model) + { + var response = await _client.PostAsJsonAsync( + $"{_conf.CrmCustomers}/{model.CompanyId}/contacts", model, _options); + + return await response.Content.ReadAsStringAsync(); + } + + public async Task GetContact(string companyId, string contactId) + { + return await _client.GetFromJsonAsync( + $"{_conf.CrmCustomers}/{companyId}/contacts/{contactId}"); + } + + public async Task> GetContacts(string companyId) + { + var response = await _client.GetAsync( + $"{_conf.CrmCustomers}/{companyId}/contacts"); + var content = await response.Content.ReadAsStringAsync(); + return string.IsNullOrWhiteSpace(content) + ? new List() + : JsonSerializer.Deserialize>(content, _options); + } + + public async Task DeleteContact(string companyId, string contactId) + { + await _client.DeleteAsync( + $"{_conf.CrmCustomers}/{companyId}/contacts/{contactId}"); + } + + public async Task UpdateContact(ContactDto model) + { + await _client.PutAsJsonAsync( + $"{_conf.CrmCustomers}/{model.CompanyId}/contacts/{model.ContactId}", model, _options); + } +} \ No newline at end of file diff --git a/Wonky.Client/Pages/CrmCompanyContactNewPage.razor b/Wonky.Client/Pages/CrmCompanyContactNewPage.razor deleted file mode 100644 index cee04f98..00000000 --- a/Wonky.Client/Pages/CrmCompanyContactNewPage.razor +++ /dev/null @@ -1,59 +0,0 @@ -@page "/companies/{CompanyId}/contacts/new" -

Ny kontakt

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
- JobTitel - - - - - Email - - - -
Fornavn - - - Efternavn - - -
Mobile - - - Telefon - - -
-
-
-
- -
-
-
\ No newline at end of file diff --git a/Wonky.Client/Pages/CrmCompanyContactNewPage.razor.cs b/Wonky.Client/Pages/CrmCompanyContactNewPage.razor.cs deleted file mode 100644 index a8ccecae..00000000 --- a/Wonky.Client/Pages/CrmCompanyContactNewPage.razor.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Forms; -using Wonky.Entity.DTO; - -namespace Wonky.Client.Pages; - -public partial class CrmCompanyContactNewPage -{ - [Parameter] public string CompanyId { get; set; } = ""; - - private EditContext ContactContext { get; set; } - private ContactDto Contact { get; set; } = new(); - private bool FormInvalid { get; set; } = true; - - private async Task SubmitContactForm() - { - - } -} \ No newline at end of file diff --git a/Wonky.Client/Pages/CrmCompanyNewPage.razor b/Wonky.Client/Pages/CrmCompanyNewPage.razor index 1cfb7ffd..24d7f591 100644 --- a/Wonky.Client/Pages/CrmCompanyNewPage.razor +++ b/Wonky.Client/Pages/CrmCompanyNewPage.razor @@ -30,29 +30,29 @@ - @if (_dk) + @if (Dk) { - + } - + - @if (_dk) + @if (Dk) { - + } - @if (_vInfos.Any() && _showInfos) + @if (VatInfos.Any() && ShowInfos) { @@ -67,7 +67,7 @@ - @foreach (var info in _vInfos) + @foreach (var info in VatInfos) { @info.VatNumber @@ -87,9 +87,9 @@ - + - + @@ -107,14 +107,14 @@ @@ -129,70 +129,83 @@ - + - + - + - + - + - + - + - + - + - + + + + + + + + + @@ -200,7 +213,7 @@
- +
\ No newline at end of file diff --git a/Wonky.Client/Pages/CrmCompanyNewPage.razor.cs b/Wonky.Client/Pages/CrmCompanyNewPage.razor.cs index 41e88122..bbcebda4 100644 --- a/Wonky.Client/Pages/CrmCompanyNewPage.razor.cs +++ b/Wonky.Client/Pages/CrmCompanyNewPage.razor.cs @@ -38,154 +38,154 @@ namespace Wonky.Client.Pages { public partial class CrmCompanyNewPage : IDisposable { - [Inject] public IToastService _toast { get; set; } - [Inject] public ILogger _logger { get; set; } - [Inject] public ILocalStorageService _storage { get; set; } - [Inject] public NavigationManager _navigator { get; set; } - [Inject] public ICrmCompanyHttpRepository _companyRepo { get; set; } - [Inject] public HttpInterceptorService _interceptor { get; set; } - [Inject] public VatInfoLookupService _vatService { get; set; } - private EditContext _editContext { get; set; } - private CompanyDto _company { get; set; } = new(); - private VirkRegInfo _virkRegInfo { get; set; } = new(); - private List _vInfos { get; set; } = new(); - private VatAddress _vatAddress { get; set; } = new(); - private bool _formInvalid = true; + [Inject] public IToastService Toaster { get; set; } + [Inject] public ILogger Logger { get; set; } + [Inject] public ILocalStorageService Storage { get; set; } + [Inject] public NavigationManager Navigator { get; set; } + [Inject] public ICrmCompanyHttpRepository CompanyRepo { get; set; } + [Inject] public HttpInterceptorService Interceptor { get; set; } + [Inject] public VatInfoLookupService VatService { get; set; } + private EditContext CompanyContext { get; set; } + private CompanyDto Company { get; set; } = new(); + private VirkRegInfo CompanyRegInfo { get; set; } = new(); + private List VatInfos { get; set; } = new(); + private VatAddress CompanyVatAddress { get; set; } = new(); + private bool FormInvalid = true; private string RegState = ""; - private DateTime _lastVisit { get; set; } - private DateTime _nextVisit { get; set; } - private bool _dk { get; set; } = true; - private bool _showInfos = true; + private DateTime LastVisit { get; set; } + private DateTime NextVisit { get; set; } + private bool Dk { get; set; } = true; + private bool ShowInfos = true; protected override async Task OnInitializedAsync() { - _editContext = new EditContext(_company); + CompanyContext = new EditContext(Company); - _editContext.OnFieldChanged += HandleFieldChanged; - _editContext.OnValidationStateChanged += ValidationChanged; + CompanyContext.OnFieldChanged += HandleFieldChanged; + CompanyContext.OnValidationStateChanged += ValidationChanged; - var ux = await _storage.GetItemAsync("_xu"); - _dk = ux.CountryCode.ToLower() == "dk"; + var ux = await Storage.GetItemAsync("_xu"); + Dk = ux.CountryCode.ToLower() == "dk"; - _company.SalesRepId = ux.Id; - _company.CountryCode = ux.CountryCode.ToLower(); + Company.SalesRepId = ux.Id; + Company.CountryCode = ux.CountryCode.ToLower(); - _lastVisit = DateTime.Now; - _nextVisit = DateTime.Now.AddDays(_company.Interval * 7); - _company.LastVisit = $"{_lastVisit:yyyy-MM-dd}"; - _company.NextVisit = $"{_nextVisit:yyyy-MM-dd}"; + LastVisit = DateTime.Now; + NextVisit = DateTime.Now.AddDays(Company.Interval * 7); + Company.LastVisit = $"{LastVisit:yyyy-MM-dd}"; + Company.NextVisit = $"{NextVisit:yyyy-MM-dd}"; - _interceptor.RegisterEvent(); - _interceptor.RegisterBeforeSendEvent(); + Interceptor.RegisterEvent(); + Interceptor.RegisterBeforeSendEvent(); } private async Task GetInfoFromName(string entityName) { - _toast.ShowInfo("Vent for firma info ..."); - _vInfos = await _vatService + Toaster.ShowInfo("Vent for firma info ..."); + VatInfos = await VatService .QueryVirkRegistry(new VirkParams {EntityName = entityName}); - if (!_vInfos.Any()) + if (!VatInfos.Any()) { - _toast.ShowError($"Firma med navn '{entityName}' findes ikke."); + Toaster.ShowError($"Firma med navn '{entityName}' findes ikke."); } } private async Task GetInfoFromAddress(VatAddress address) { - _showInfos = true; - _toast.ShowInfo("Vent for adresse info ..."); - _vInfos = await _vatService.QueryVirkRegistry( + ShowInfos = true; + Toaster.ShowInfo("Vent for adresse info ..."); + VatInfos = await VatService.QueryVirkRegistry( new VirkParams { StreetName = address.StreetName, HouseNumber = address.HouseNumber, ZipCode = address.ZipCode }); - if (!_vInfos.Any()) + if (!VatInfos.Any()) { - _toast.ShowWarning($"Ingen data for adresse ..."); + Toaster.ShowWarning($"Ingen data for adresse ..."); } } private async Task GetInfoFromVat(string vatNumber) { - _showInfos = true; - _toast.ShowInfo("Vent for firma info ..."); - _vInfos = await _vatService + ShowInfos = true; + Toaster.ShowInfo("Vent for firma info ..."); + VatInfos = await VatService .QueryVirkRegistry(new VirkParams {VatNumber = vatNumber}); - if (!_vInfos.Any()) + if (!VatInfos.Any()) { - _toast.ShowError($"Firma med CVR '{vatNumber}' findes ikke."); + Toaster.ShowError($"Firma med CVR '{vatNumber}' findes ikke."); } } private void SelectCompany(string vatNumber) { - _showInfos = false; - _virkRegInfo = (from x in _vInfos where x.VatNumber == vatNumber select x).First(); - RegState = _virkRegInfo.States[^1].State == "NORMAL" ? "the-good" : "the-ugly"; - _company.Name = _virkRegInfo.Name; - _company.Address1 = _virkRegInfo.Address; - _company.Address2 = _virkRegInfo.CoName; - _company.ZipCode = _virkRegInfo.ZipCode; - _company.City = _virkRegInfo.City; - _company.VatNumber = _virkRegInfo.VatNumber; - _company.ValidVat = 1; + ShowInfos = false; + CompanyRegInfo = (from x in VatInfos where x.VatNumber == vatNumber select x).First(); + RegState = CompanyRegInfo.States[^1].State == "NORMAL" ? "the-good" : "the-ugly"; + Company.Name = CompanyRegInfo.Name; + Company.Address1 = CompanyRegInfo.Address; + Company.Address2 = CompanyRegInfo.CoName; + Company.ZipCode = CompanyRegInfo.ZipCode; + Company.City = CompanyRegInfo.City; + Company.VatNumber = CompanyRegInfo.VatNumber; + Company.ValidVat = 1; StateHasChanged(); } private async Task SubmitCompanyForm() { - _formInvalid = true; - _company.LastVisit = $"{_lastVisit:yyyy-MM-dd}"; - _company.NextVisit = $"{_nextVisit:yyyy-MM-dd}"; + FormInvalid = true; + Company.LastVisit = $"{LastVisit:yyyy-MM-dd}"; + Company.NextVisit = $"{NextVisit:yyyy-MM-dd}"; - var newId = await _companyRepo.CreateCompany(_company); + var newId = await CompanyRepo.CreateCompany(Company); if (!string.IsNullOrWhiteSpace(newId)) { - _toast.ShowSuccess($"'{_company.Name}' er oprettet i CRM."); - _navigator.NavigateTo($"/companies/{newId}"); + Toaster.ShowSuccess($"'{Company.Name}' er oprettet i CRM."); + Navigator.NavigateTo($"/companies/{newId}"); } else { - _toast.ShowWarning($"'{_company.Name}' IKKE oprettet."); - _formInvalid = false; + Toaster.ShowWarning($"'{Company.Name}' IKKE oprettet."); + FormInvalid = false; } } private void HandleFieldChanged(object sender, FieldChangedEventArgs e) { - _nextVisit = _lastVisit.AddDays(7 * _company.Interval); + NextVisit = LastVisit.AddDays(7 * Company.Interval); - if (!_company.ValidDateSpan()) + if (!Company.ValidDateSpan()) { - _toast.ShowError("Dato for næste besøg skal ligge efter sidste besøg."); - _formInvalid = true; + Toaster.ShowError("Dato for næste besøg skal ligge efter sidste besøg."); + FormInvalid = true; } else { - _formInvalid = !_editContext.Validate(); + FormInvalid = !CompanyContext.Validate(); } StateHasChanged(); } private void ValidationChanged(object sender, ValidationStateChangedEventArgs e) { - _formInvalid = true; + FormInvalid = true; - _editContext.OnFieldChanged -= HandleFieldChanged; + CompanyContext.OnFieldChanged -= HandleFieldChanged; - _editContext = new EditContext(_company); + CompanyContext = new EditContext(Company); - _formInvalid = !_editContext.Validate(); + FormInvalid = !CompanyContext.Validate(); - _editContext.OnFieldChanged += HandleFieldChanged; - _editContext.OnValidationStateChanged -= ValidationChanged; + CompanyContext.OnFieldChanged += HandleFieldChanged; + CompanyContext.OnValidationStateChanged -= ValidationChanged; } public void Dispose() { - _interceptor.DisposeEvent(); - _editContext.OnFieldChanged -= HandleFieldChanged; - _editContext.OnValidationStateChanged -= ValidationChanged; + Interceptor.DisposeEvent(); + CompanyContext.OnFieldChanged -= HandleFieldChanged; + CompanyContext.OnValidationStateChanged -= ValidationChanged; } } } diff --git a/Wonky.Client/Pages/CrmCompanyViewPage.razor b/Wonky.Client/Pages/CrmCompanyViewPage.razor index 3a3dfa89..f54ce594 100644 --- a/Wonky.Client/Pages/CrmCompanyViewPage.razor +++ b/Wonky.Client/Pages/CrmCompanyViewPage.razor @@ -27,227 +27,237 @@ {

Ring til kontoret. Denne konto er spærret med kode '@Company.Blocked'

-
+ }
-
-

@Company.Name

-
- @if (_dk) - { -
- - @if (_vInfos.Any()) - { -
- + - + - - + +
Moms/Org Reg.Moms/Org Reg. - - + + TelefonTelefon - - + +
FirmanavnFirmanavn - - + + AttentionAttention - - + +
Adresse1Adresse1 - - + + Adresse2Adresse2 - - + +
PostnrPostnr - - + + BynavnBynavn - - + +
MobilMobil - - + + EmailEmail - - + + +
OBS + + +
Notater +
- - - - - - - - - - - @foreach (var info in _vInfos) - { - - - - - - - - } - -
CVR ORGNavnStatus
@info.VatNumber@info.Name@info.States[^1].State - - - -
- } - - } - - -
- +
+

@Company.Name

+
+ @if (Dk) + { +
+ + @if (VatInfos.Any()) + { +
+ + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @foreach (var info in VatInfos) + { + + + + + + + + }
CVR ORGNavnStatus
BEMÆRK - @if (string.IsNullOrWhiteSpace(Company.Note)) - { - - } - else - { - - } - -
- CVR/ORG - - - - - - @* *@ - - Konto - - -
- Firmanavn - - - - - Attention - - - -
- Adresse1 - - - - - Adresse2 - - - -
- Postnr - - - - - Bynavn - - - -
- Epost - - - - - Telefon - - - - - Mobil - - - -
- Næste besøg - - - - - - - Besøgt - - -
- Interval (uger) - - - - - @if (Company.HasFolded == 1) - { - - } -
@info.VatNumber@info.Name@info.States[^1].State + + + +
-
- } else { - + } - \ No newline at end of file + + \ No newline at end of file diff --git a/Wonky.Client/Pages/CrmCompanyViewPage.razor.cs b/Wonky.Client/Pages/CrmCompanyViewPage.razor.cs index 910ded38..e4ce0e31 100644 --- a/Wonky.Client/Pages/CrmCompanyViewPage.razor.cs +++ b/Wonky.Client/Pages/CrmCompanyViewPage.razor.cs @@ -13,6 +13,7 @@ // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // +using System.CodeDom.Compiler; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; @@ -39,81 +40,85 @@ public partial class CrmCompanyViewPage : IDisposable { [Parameter] public string CompanyId { get; set; } = ""; [Inject] public IToastService Toaster { get; set; } - [Inject] public ILogger _logger { get; set; } - [Inject] public NavigationManager _navigator { get; set; } - [Inject] public ICrmCompanyHttpRepository _companyRepo { get; set; } + [Inject] public ILogger Logger { get; set; } + [Inject] public NavigationManager Navigator { get; set; } + [Inject] public ICrmCompanyHttpRepository CompanyRepo { get; set; } [Inject] public ICrmHistoryHttpRepository HistoryRepo { get; set; } - [Inject] public HttpInterceptorService _interceptor { get; set; } - [Inject] public VatInfoLookupService _vatService { get; set; } - [Inject] public ILocalStorageService _storage { get; set; } - private CompanyDto Company { get; set; } = new(); - private EditContext _editContext { get; set; } - private List _vInfos { get; set; } = new(); - private VirkRegInfo _virkRegInfo { get; set; } = new(); - private DateTime _lastVisit { get; set; } - private DateTime _nextVisit { get; set; } - private string _vatState { get; set; } = "the-ugly"; - private VatAddress _vatAddress = new(); - private bool _validVat; - private bool _hasFolded; - private bool _formInvalid = true; - private string _orgVat; - private string _countryCode = "dk"; - private string _visitState = "the-ugly"; - private int _enableActivity = 1; - private bool _hideButtons = false; - private string _actionLink = ""; - private bool _working; - private string _btnUpdateText = "Opdater"; - private bool _dk { get; set; } = true; - private int _isDirty { get; set; } - private int _vatUpdated { get; set; } - private bool Loading { get; set; } = true; - - private VatLookupDkModal _vatLookupModal { get; set; } = new(); - + [Inject] public ICrmContactHttpRepository ContactRepo { get; set; } + [Inject] public HttpInterceptorService Interceptor { get; set; } + [Inject] public VatInfoLookupService VatService { get; set; } + [Inject] public ILocalStorageService Storage { get; set; } private readonly JsonSerializerOptions _options = new () { PropertyNameCaseInsensitive = true }; + private CompanyDto Company { get; set; } = new(); + private EditContext CompanyContext { get; set; } + private List VatInfos { get; set; } = new(); + private VirkRegInfo CompanyRegInfo { get; set; } = new(); + private DateTime LastVisit { get; set; } + private DateTime NextVisit { get; set; } + private string VatState { get; set; } = "the-ugly"; + private VatAddress CompanyVatAddress = new(); + private bool ValidVat; + private bool HasFolded; + private bool FormInvalid = true; + private string CurrentOrgVat; + private string CountryCode = "dk"; + private string VisitState = "the-ugly"; + private int EnableActivity = 1; + private bool HideButtons = false; + private string ActionLink = ""; + private bool Working; + private string BtnUpdateText = "Opdater"; + private bool Dk { get; set; } = true; + private int IsDirty { get; set; } + private int VatUpdated { get; set; } + private bool Loading { get; set; } = true; + private List Contacts { get; set; } = new(); + private VatLookupDkModal VatLookupPopup { get; set; } = new(); + private ContactDto SelectedContact { get; set; } = new(); + private ContactDto DefaultContact { get; set; } = new(); + private ContactModal ContactPopup { get; set; } = new(); protected override async Task OnInitializedAsync() { - var ux = await _storage.GetItemAsync("_xu"); - _countryCode = ux.CountryCode; - _dk = ux.CountryCode.ToLower() == "dk"; - Company = await _companyRepo.GetCompanyById(CompanyId); - _interceptor.RegisterEvent(); - _interceptor.RegisterBeforeSendEvent(); + DefaultContact = new ContactDto { CompanyId = CompanyId, ContactId = "", FirstName = ""}; + var ux = await Storage.GetItemAsync("_xu"); + CountryCode = ux.CountryCode; + Dk = ux.CountryCode.ToLower() == "dk"; + Company = await CompanyRepo.GetCompanyById(CompanyId); + Interceptor.RegisterEvent(); + Interceptor.RegisterBeforeSendEvent(); // Company = await _companyRepo.GetCompanyById(CompanyId); - _orgVat = Company.VatNumber; + CurrentOrgVat = Company.VatNumber; Company.CountryCode = ux.CountryCode.ToLower(); - _enableActivity = Company.ValidVat; + EnableActivity = Company.ValidVat; // override if canvas which has account property as empty string or "NY" if (Company.Account == "NY" || string.IsNullOrWhiteSpace(Company.Account)) - _enableActivity = 1; + EnableActivity = 1; - if (_dk) - _vatAddress = PrepareVatAddress(Company); + if (Dk) + CompanyVatAddress = PrepareVatAddress(Company); if (Company.Interval == 0) Company.Interval = 8; - _lastVisit = DateTime.Parse(Company.LastVisit); - _nextVisit = DateTime.Parse(Company.NextVisit); + LastVisit = DateTime.Parse(Company.LastVisit); + NextVisit = DateTime.Parse(Company.NextVisit); - if (_lastVisit.Year < 2020) - _lastVisit = DateTime.Parse("2020-01-01"); + if (LastVisit.Year < 2020) + LastVisit = DateTime.Parse("2020-01-01"); if (!Company.ValidDateSpan()) - _nextVisit = _lastVisit.AddDays(Company.Interval * 7); + NextVisit = LastVisit.AddDays(Company.Interval * 7); - _visitState = Utils.GetVisitState($"{_nextVisit:yyyy-MM-dd}"); - _actionLink = $"/companies/{CompanyId}/activities/new"; // used when drawing visit button + VisitState = Utils.GetVisitState($"{NextVisit:yyyy-MM-dd}"); + ActionLink = $"/companies/{CompanyId}/activities/new"; // used when drawing visit button if(Company.HasFolded == 1) { // this is only used if user has selected to show all customers - _hasFolded = true; - _vatState = "the-dead"; - _visitState = "the-dead"; + HasFolded = true; + VatState = "the-dead"; + VisitState = "the-dead"; } else { @@ -121,21 +126,53 @@ public partial class CrmCompanyViewPage : IDisposable if (Company.ValidVat == 0 && !string.IsNullOrWhiteSpace(Company.VatNumber)) Company.ValidVat = VatUtils.ValidateFormat(Company.CountryCode, Company.VatNumber) ? 1 : 0; // flags - _validVat = Company.ValidVat == 1; // flag set if company has a valid vatNumber - _vatState = Company.ValidVat == 1 ? "the-good" : "no-vat"; // assign css class + ValidVat = Company.ValidVat == 1; // flag set if company has a valid vatNumber + VatState = Company.ValidVat == 1 ? "the-good" : "no-vat"; // assign css class } - _editContext = new EditContext(Company); - _editContext.OnFieldChanged += HandleFieldChanged; - _editContext.OnValidationStateChanged += ValidationChanged; + CompanyContext = new EditContext(Company); + CompanyContext.OnFieldChanged += HandleFieldChanged; + CompanyContext.OnValidationStateChanged += ValidationChanged; await SyncCompanyHistory(); + Contacts = await ContactRepo.GetContacts(CompanyId); } private void ForceActivity() { - _enableActivity = _enableActivity == 0 ? 1 : 0; + EnableActivity = EnableActivity == 0 ? 1 : 0; } + private void OpenContact(ContactDto contact) + { + SelectedContact = contact; + ContactPopup.Show(); + } + + private async Task SaveContact(ContactDto contact) + { + Console.WriteLine(JsonSerializer.Serialize(contact)); + + if (string.IsNullOrWhiteSpace(contact.ContactId)) + { + Console.WriteLine("create"); + await ContactRepo.CreateContact(contact); + } + else + { + Console.WriteLine("update"); + await ContactRepo.UpdateContact(contact); + } + Contacts = await ContactRepo.GetContacts(CompanyId); + SelectedContact = new ContactDto(); + } + + private async Task DeleteContact(string contactId) + { + await ContactRepo.DeleteContact(CompanyId, contactId); + Contacts = await ContactRepo.GetContacts(CompanyId); + SelectedContact = new ContactDto(); + } + private async Task SyncCompanyHistory() { await HistoryRepo.RpcSyncErpToCrm(CompanyId, Company.HistorySync); @@ -143,39 +180,39 @@ public partial class CrmCompanyViewPage : IDisposable private void HandleFieldChanged(object sender, FieldChangedEventArgs e) { - _nextVisit = _lastVisit.AddDays(Company.Interval * 7); + NextVisit = LastVisit.AddDays(Company.Interval * 7); // simple validation of VAT format if (!VatUtils.ValidateFormat(Company.CountryCode, Company.VatNumber)) { - _formInvalid = true; + FormInvalid = true; } else { - _formInvalid = !_editContext.Validate(); + FormInvalid = !CompanyContext.Validate(); } - if(_vatUpdated == 0 && e.FieldIdentifier.FieldName != "Note") - _isDirty = 1; + if(VatUpdated == 0 && e.FieldIdentifier.FieldName != "Note" && e.FieldIdentifier.FieldName != "CrmNotes") + IsDirty = 1; StateHasChanged(); } private void ValidationChanged(object sender, ValidationStateChangedEventArgs e) { - _formInvalid = false; - _editContext.OnFieldChanged -= HandleFieldChanged; - _editContext.OnValidationStateChanged -= ValidationChanged; + FormInvalid = false; + CompanyContext.OnFieldChanged -= HandleFieldChanged; + CompanyContext.OnValidationStateChanged -= ValidationChanged; - _editContext = new EditContext(Company); + CompanyContext = new EditContext(Company); - _formInvalid = _editContext.Validate(); + FormInvalid = CompanyContext.Validate(); - _editContext.OnFieldChanged += HandleFieldChanged; - _editContext.OnValidationStateChanged += ValidationChanged; + CompanyContext.OnFieldChanged += HandleFieldChanged; + CompanyContext.OnValidationStateChanged += ValidationChanged; } private async Task SubmitUpdate() { - _working = true; + Working = true; // simple format validation if CRM indicates invalid vatNumber if (!VatUtils.ValidateFormat(Company.CountryCode, Company.VatNumber)) { @@ -185,41 +222,38 @@ public partial class CrmCompanyViewPage : IDisposable } Toaster.ShowInfo("Vent venligst ...."); //_hideButtons = true; - Company.LastVisit = $"{_lastVisit:yyyy-MM-dd}"; - Company.NextVisit = $"{_nextVisit:yyyy-MM-dd}"; + Company.LastVisit = $"{LastVisit:yyyy-MM-dd}"; + Company.NextVisit = $"{NextVisit:yyyy-MM-dd}"; Company.IsHidden = 0; // flag if backend should update ERP system - Company.UpdateErpVat = _vatUpdated; + Company.UpdateErpVat = VatUpdated; // flag base info has changed - Company.IsDirty = _isDirty; + Company.IsDirty = IsDirty; + + var success = await CompanyRepo.UpdateCompany(CompanyId, Company ); - var success = await _companyRepo.UpdateCompany(CompanyId, Company ); Toaster.ShowSuccess("Opdatering er afsendt. Der går nogle minutter inden data er opdateret."); - Company = await _companyRepo.GetCompanyById(Company.CompanyId); + Company = await CompanyRepo.GetCompanyById(Company.CompanyId); Company.ValidVat = 1; - _enableActivity = 1; - if (_virkRegInfo.States[0].State.ToLower() != "normal") - { - Company.HasFolded = 1; - } - StateHasChanged(); - _working = false; + EnableActivity = 1; + Working = false; Toaster.ClearAll(); + StateHasChanged(); } private async Task GetInfoFromAddress(VatAddress address) { Toaster.ShowInfo("Vent for adresse info ..."); - _vInfos = await _vatService.QueryVirkRegistry( + VatInfos = await VatService.QueryVirkRegistry( new VirkParams { StreetName = address.StreetName, HouseNumber = address.HouseNumber, ZipCode = address.ZipCode }); - if (!_vInfos.Any()) + if (!VatInfos.Any()) { Toaster.ShowWarning($"Ingen data fundet ..."); } @@ -256,65 +290,65 @@ public partial class CrmCompanyViewPage : IDisposable private void CallVatLookupModal() { - _vatLookupModal.Show(); + VatLookupPopup.Show(); } private void OnSelectedCompany(VirkRegInfo regInfo) { - _validVat = regInfo.States[0].State.ToLower() == "normal"; - Company.HasFolded = _validVat ? 1 : 0; - _enableActivity = _validVat ? 1 : 0; - _vatState = regInfo.States[0].State.ToLower() == "normal" ? "the-good" : "the-dead"; + ValidVat = regInfo.States[0].State.ToLower() == "normal"; + Company.HasFolded = ValidVat ? 1 : 0; + EnableActivity = ValidVat ? 1 : 0; + VatState = regInfo.States[0].State.ToLower() == "normal" ? "the-good" : "the-dead"; if (regInfo.SyncAll) { - Company.VatNumber = _virkRegInfo.VatNumber; - Company.Name = _virkRegInfo.Name; - Company.Address1 = _virkRegInfo.Address; - Company.Address2 = _virkRegInfo.CoName; - Company.ZipCode = _virkRegInfo.ZipCode; - Company.City = _virkRegInfo.City; - _isDirty = 1; + Company.VatNumber = CompanyRegInfo.VatNumber; + Company.Name = CompanyRegInfo.Name; + Company.Address1 = CompanyRegInfo.Address; + Company.Address2 = CompanyRegInfo.CoName; + Company.ZipCode = CompanyRegInfo.ZipCode; + Company.City = CompanyRegInfo.City; + IsDirty = 1; } else { - Company.VatNumber = _virkRegInfo.VatNumber; - _vatUpdated = 1; + Company.VatNumber = CompanyRegInfo.VatNumber; + VatUpdated = 1; } StateHasChanged(); } private void SelectCompany(string vatNumber, bool syncAll) { - _virkRegInfo = (from x in _vInfos where x.VatNumber == vatNumber select x).First(); - _validVat = _virkRegInfo.States[0].State.ToLower() == "normal"; - Company.HasFolded = _validVat ? 1 : 0; - _enableActivity = _validVat ? 1 : 0; - _vatState = _virkRegInfo.States[0].State.ToLower() == "normal" ? "the-good" : "the-dead"; + CompanyRegInfo = (from x in VatInfos where x.VatNumber == vatNumber select x).First(); + ValidVat = CompanyRegInfo.States[0].State.ToLower() == "normal"; + Company.HasFolded = ValidVat ? 1 : 0; + EnableActivity = ValidVat ? 1 : 0; + VatState = CompanyRegInfo.States[0].State.ToLower() == "normal" ? "the-good" : "the-dead"; if (syncAll) { - Company.VatNumber = _virkRegInfo.VatNumber; - Company.Name = _virkRegInfo.Name; - Company.Address1 = _virkRegInfo.Address; - Company.Address2 = _virkRegInfo.CoName; - Company.ZipCode = _virkRegInfo.ZipCode; - Company.City = _virkRegInfo.City; - _isDirty = 1; + Company.VatNumber = CompanyRegInfo.VatNumber; + Company.Name = CompanyRegInfo.Name; + Company.Address1 = CompanyRegInfo.Address; + Company.Address2 = CompanyRegInfo.CoName; + Company.ZipCode = CompanyRegInfo.ZipCode; + Company.City = CompanyRegInfo.City; + IsDirty = 1; } else { - Company.VatNumber = _virkRegInfo.VatNumber; - _vatUpdated = 1; + Company.VatNumber = CompanyRegInfo.VatNumber; + VatUpdated = 1; } // empty list - _vInfos = new List(); + VatInfos = new List(); StateHasChanged(); } public void Dispose() { - _interceptor.DisposeEvent(); - _editContext.OnFieldChanged -= HandleFieldChanged; - _editContext.OnValidationStateChanged -= ValidationChanged; + Interceptor.DisposeEvent(); + CompanyContext.OnFieldChanged -= HandleFieldChanged; + CompanyContext.OnValidationStateChanged -= ValidationChanged; } } \ No newline at end of file diff --git a/Wonky.Client/Program.cs b/Wonky.Client/Program.cs index ba76a8d1..c554f327 100644 --- a/Wonky.Client/Program.cs +++ b/Wonky.Client/Program.cs @@ -61,11 +61,13 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/Wonky.Client/Shared/ContactModal.razor b/Wonky.Client/Shared/ContactModal.razor new file mode 100644 index 00000000..20a66cc3 --- /dev/null +++ b/Wonky.Client/Shared/ContactModal.razor @@ -0,0 +1,76 @@ +@* +// Copyright (C) 2022 FCS Frede's Computer Services. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] +// +*@ +@using Wonky.Client.Components +@using Wonky.Client.Helpers +@using System.Text.Json + +@if (_showBackdrop) +{ + +} \ No newline at end of file diff --git a/Wonky.Client/Shared/ContactModal.razor.cs b/Wonky.Client/Shared/ContactModal.razor.cs new file mode 100644 index 00000000..88a14045 --- /dev/null +++ b/Wonky.Client/Shared/ContactModal.razor.cs @@ -0,0 +1,97 @@ +// Copyright (C) 2022 FCS Frede's Computer Services. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] +// + +using System.Text.Json; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using Wonky.Client.HttpInterceptors; +using Wonky.Client.HttpInterfaces; +using Wonky.Client.HttpRepository; +using Wonky.Client.Models; +using Wonky.Client.Services; +using Wonky.Entity.DTO; +using Wonky.Entity.Requests; +using Wonky.Entity.Views; + +namespace Wonky.Client.Shared; + +public partial class ContactModal : IDisposable +{ + [Parameter] public ContactDto ParamContact { get; set; } = new(); + [Parameter] public string CompanyName { get; set; } = ""; + [Parameter] public ICrmContactHttpRepository ContactRepo { get; set; } + [Parameter] public HttpInterceptorService Interceptor { get; set; } + [Parameter] public EventCallback OnSaveClicked { get; set; } + [Parameter] public EventCallback OnDeleteClicked { get; set; } + private ContactDto Contact { get; set; } = new(); + private string _modalDisplay = ""; + private bool _showBackdrop; + private bool DisableDelete { get; set; } + private bool FormInvalid { get; set; } + + protected override void OnParametersSet() + { + Contact = new ContactDto + { + CompanyId = ParamContact.CompanyId, + ContactId = ParamContact.ContactId, + FirstName = ParamContact.FirstName, + LastName = ParamContact.LastName, + JobTitle = ParamContact.JobTitle, + PhoneDirect = ParamContact.PhoneDirect + }; + + if (string.IsNullOrWhiteSpace(Contact.ContactId)) + DisableDelete = true; + } + + protected override void OnInitialized() + { + Interceptor.RegisterEvent(); + Interceptor.RegisterBeforeSendEvent(); + } + + private void DeleteContact() + { + OnDeleteClicked.InvokeAsync(Contact.ContactId); + Hide(); + } + + private void SubmitContact() + { + OnSaveClicked.InvokeAsync(Contact); + Hide(); + } + + public void Show() + { + _modalDisplay = "block;"; + _showBackdrop = true; + StateHasChanged(); + } + + private void Hide() + { + _modalDisplay = "none;"; + _showBackdrop = false; + Contact = new ContactDto(); + StateHasChanged(); + } + + public void Dispose() + { + Interceptor.DisposeEvent(); + } +} \ No newline at end of file diff --git a/Wonky.Client/Wonky.Client.csproj b/Wonky.Client/Wonky.Client.csproj index e5943b3e..40c777ac 100644 --- a/Wonky.Client/Wonky.Client.csproj +++ b/Wonky.Client/Wonky.Client.csproj @@ -11,10 +11,10 @@ - - - - + + + + diff --git a/Wonky.Client/wwwroot/appsettings.json b/Wonky.Client/wwwroot/appsettings.json index d690bb90..93d74fb8 100644 --- a/Wonky.Client/wwwroot/appsettings.json +++ b/Wonky.Client/wwwroot/appsettings.json @@ -1,7 +1,7 @@ { "appInfo": { "name": "Wonky Client", - "version": "0.41.1", + "version": "0.45.1", "rc": true, "sandBox": false, "image": "grumpy-coder.png" diff --git a/Wonky.Entity/DTO/CompanyDto.cs b/Wonky.Entity/DTO/CompanyDto.cs index dc12956c..5056eb10 100644 --- a/Wonky.Entity/DTO/CompanyDto.cs +++ b/Wonky.Entity/DTO/CompanyDto.cs @@ -29,11 +29,15 @@ public class CompanyDto public string Name { get; set; } = ""; /// - /// Note + /// Alert /// [MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")] public string Note { get; set; } = ""; /// + /// Crm note + /// + public string CrmNotes { get; set; } = ""; + /// /// Postal code /// [Required(ErrorMessage = "Postnummer skal udfyldes")] diff --git a/Wonky.Entity/DTO/ContactDto.cs b/Wonky.Entity/DTO/ContactDto.cs index 5ac75f3a..f150b8f2 100644 --- a/Wonky.Entity/DTO/ContactDto.cs +++ b/Wonky.Entity/DTO/ContactDto.cs @@ -4,25 +4,25 @@ namespace Wonky.Entity.DTO; public class ContactDto { - [Required(ErrorMessage = "CompanyId")] - [MaxLength(128, ErrorMessage = "CompanyId mangler")] public string CompanyId { get; set; } = ""; + public string ContactId { get; set; } = ""; + [Required(ErrorMessage = "Fornavn skal udfyldes.")] [MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn")] public string FirstName { get; set; } = ""; - [MaxLength(50, ErrorMessage = "Du kan højst bruge 50 tegn.")] - public string JobTitle { get; set; } = ""; - [MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn.")] public string LastName { get; set; } = ""; + [MaxLength(50, ErrorMessage = "Du kan højst bruge 50 tegn.")] + public string JobTitle { get; set; } = ""; + [MaxLength(80, ErrorMessage = "Du kan højst bruge 80 tegn.")] public string Email { get; set; } = ""; [MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn.")] - public string Phone { get; set; } = ""; + public string PhoneDirect { get; set; } = ""; [MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn.")] public string Mobile { get; set; } = "";