wip 0.3.7-beta
This commit is contained in:
parent
e5e3b1024a
commit
91a8e6f346
42 changed files with 727 additions and 574 deletions
|
@ -1,13 +1,15 @@
|
||||||
@if (Enabled)
|
@if (Enabled == 1)
|
||||||
{
|
{
|
||||||
<a type="button" class="btn btn-primary" href="/company/@CompanyId/activity">Opret Besøg</a>
|
<a type="button" class="btn btn-success" href="/company/@CompanyId/activity">Opret Besøg</a>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<a type="button" class="btn btn-primary disabled" aria-disabled="true">Opret Besøg</a>
|
<a type="button" class="btn btn-outline-secondary disabled" aria-disabled="true">Opret Besøg</a>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter] public string? CompanyId { get; set; }
|
|
||||||
[Parameter] public bool Enabled { get; set; }
|
[Parameter] public string CompanyId { get; set; } = "";
|
||||||
|
[Parameter]public int Enabled { get; set; }
|
||||||
|
|
||||||
}
|
}
|
|
@ -16,9 +16,13 @@
|
||||||
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||||
//
|
//
|
||||||
*@
|
*@
|
||||||
<span class="version">@Version</span>@if(IsBeta){<span class="version">-beta</span>}
|
<span class="version">@_app?.Version</span>@if(_app!.IsBeta){<span class="version">-beta</span>}
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
private const string Version = "0.3.1";
|
[Inject] IOptions<AppInfo?>? AppInfo { get; set; }
|
||||||
private const bool IsBeta = true;
|
private AppInfo? _app;
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
_app = AppInfo?.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,39 +10,39 @@
|
||||||
<td class="color-code">
|
<td class="color-code">
|
||||||
<img class="state the-good rounded-circle me-1" src="state.png" alt="state"/>
|
<img class="state the-good rounded-circle me-1" src="state.png" alt="state"/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="align-middle">
|
||||||
Ok
|
Ok
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td class="align-middle">
|
||||||
<img class="state the-bad rounded-circle me-1" src="state.png" alt="state"/>
|
<img class="state the-bad rounded-circle me-1" src="state.png" alt="state"/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="align-middle">
|
||||||
Planlæg besøg
|
Planlæg besøg
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td class="align-middle">
|
||||||
<img class="state the-ugly rounded-circle me-1" src="state.png" alt="state"/>
|
<img class="state the-ugly rounded-circle me-1" src="state.png" alt="state"/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="align-middle">
|
||||||
Inteval overskredet
|
Interval overskredet
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td class="align-middle">
|
||||||
<img class="state the-draw rounded-circle me-1" src="state.png" alt="state"/>
|
<img class="state the-draw rounded-circle me-1" src="state.png" alt="state"/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="align-middle">
|
||||||
Opdatering nødvendig
|
Opdatering nødvendig
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td class="align-middle">
|
||||||
<img class="state the-dead rounded-circle me-1" src="state.png" alt="state"/>
|
<img class="state the-dead rounded-circle me-1" src="state.png" alt="state"/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="align-middle">
|
||||||
Virksomhed ophørt
|
Virksomhed ophørt
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -34,13 +34,23 @@
|
||||||
@foreach (var company in Companies)
|
@foreach (var company in Companies)
|
||||||
{
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td><DisplayStateComponent StateClass="@(company.HasFolded == 1 ? "the-dead" : Utils.GetVisitState(company.NextVisit))"></DisplayStateComponent></td>
|
<td class="align-middle">
|
||||||
<td>@company.Name</td>
|
<DisplayStateComponent StateClass="@(company.HasFolded == 1
|
||||||
<td>@company.Account</td>
|
? "the-dead" : Utils.GetVisitState(company.NextVisit))">
|
||||||
<td>@company.City</td>
|
</DisplayStateComponent>
|
||||||
<td>
|
</td>
|
||||||
<a class="btn btn-info" href="/company/@company.CompanyId">Vis</a>
|
<td class="align-middle">
|
||||||
<CreateActivityButton CompanyId="@company.CompanyId" Enabled="@company.ValidVat"></CreateActivityButton>
|
@company.Name
|
||||||
|
</td>
|
||||||
|
<td class="align-middle">
|
||||||
|
@company.Account
|
||||||
|
</td>
|
||||||
|
<td class="align-middle">
|
||||||
|
@company.City
|
||||||
|
</td>
|
||||||
|
<td class="align-middle">
|
||||||
|
<a class="btn btn-edit" href="/company/@company.CompanyId/update">Rediger</a>
|
||||||
|
<ActivityButton CompanyId="@company.CompanyId" Enabled="@company.ValidVat"></ActivityButton>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,17 +29,13 @@ namespace Wonky.Client.Components
|
||||||
[Parameter] public List<CompanyDto> Companies { get; set; } = new();
|
[Parameter] public List<CompanyDto> Companies { get; set; } = new();
|
||||||
[Parameter] public EventCallback<string> OnDelete { get; set; }
|
[Parameter] public EventCallback<string> OnDelete { get; set; }
|
||||||
[Parameter] public EventCallback<string> OnSelect { get; set; }
|
[Parameter] public EventCallback<string> OnSelect { get; set; }
|
||||||
[Inject] public NavigationManager NavManager { get; set; }
|
|
||||||
[Inject] public VatUtils VatUtils { get; set; }
|
|
||||||
[Inject] public ILocalStorageService Storage { get; set; }
|
|
||||||
|
|
||||||
private Confirmation _confirmation = new ();
|
private Confirmation _confirmation = new ();
|
||||||
private string _companyId = string.Empty;
|
private string _companyId = "";
|
||||||
private UserInfoView _user = new();
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
_user = await Storage.GetItemAsync<UserInfoView>("_xu").ConfigureAwait(true);
|
await base.OnInitializedAsync();
|
||||||
}
|
}
|
||||||
private void CallConfirmationModal(string companyId)
|
private void CallConfirmationModal(string companyId)
|
||||||
{
|
{
|
||||||
|
@ -52,10 +48,5 @@ namespace Wonky.Client.Components
|
||||||
_confirmation.Hide();
|
_confirmation.Hide();
|
||||||
await OnDelete.InvokeAsync(_companyId);
|
await OnDelete.InvokeAsync(_companyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NavigateCompany(string companyId)
|
|
||||||
{
|
|
||||||
NavManager.NavigateTo($"/company/{companyId}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,5 +17,5 @@
|
||||||
|
|
||||||
<img class="img-fluid float-start rounded-circle state @StateClass me-1" src="state.png" alt="state"/>
|
<img class="img-fluid float-start rounded-circle state @StateClass me-1" src="state.png" alt="state"/>
|
||||||
@code{
|
@code{
|
||||||
[Parameter] public string StateClass { get; set; } = "the-dead";
|
[Parameter] public string StateClass { get; set; } = "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ public partial class Home
|
||||||
|
|
||||||
_workDate = DateTime.Parse(_prefs.WorkDate).ToLongDateString();
|
_workDate = DateTime.Parse(_prefs.WorkDate).ToLongDateString();
|
||||||
|
|
||||||
Activities = await ActivityRepo.GetActivities(_prefs.WorkDate).ConfigureAwait(true);
|
Activities = await ActivityRepo.GetActivities(_prefs.WorkDate);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,14 +30,14 @@
|
||||||
@foreach (var salesItem in SalesItems)
|
@foreach (var salesItem in SalesItems)
|
||||||
{
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td class="align-middle">
|
||||||
@salesItem.Name
|
@salesItem.Name
|
||||||
</td>
|
</td>
|
||||||
<td>@salesItem.ShortName</td>
|
<td class="align-middle">@salesItem.ShortName</td>
|
||||||
<td>
|
<td class="align-middle">
|
||||||
@salesItem.Sku
|
@salesItem.Sku
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="align-middle">
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
@foreach (var rate in salesItem.Rates)
|
@foreach (var rate in salesItem.Rates)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<DataAnnotationsValidator/>
|
<DataAnnotationsValidator/>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<InputText id="vatNumber" class="form-control" placeholder="reg.nr. eks. 26991765"
|
<InputText id="vatNumber" class="form-control" placeholder="26991765"
|
||||||
@bind-Value="@VatNumber"/>
|
@bind-Value="@VatNumber"/>
|
||||||
<ValidationMessage For="@(() => VatNumber)"/>
|
<ValidationMessage For="@(() => VatNumber)"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -27,11 +27,14 @@ public static class Utils
|
||||||
|
|
||||||
public static string GetVisitState(string dtNextVisit)
|
public static string GetVisitState(string dtNextVisit)
|
||||||
{
|
{
|
||||||
if (dtNextVisit == "1970-01-01" || !DateTime.TryParse(dtNextVisit, out var dtNext))
|
if (dtNextVisit is "0001-01-01" or "1970-01-01")
|
||||||
return "the-draw";
|
return "the-draw";
|
||||||
|
|
||||||
var dtNow = DateTime.Now;
|
var dtNow = DateTime.Now;
|
||||||
if (dtNow >= dtNext)
|
var dtNext = DateTime.Parse(dtNextVisit);
|
||||||
|
if (dtNow > dtNext)
|
||||||
return "the-ugly";
|
return "the-ugly";
|
||||||
|
|
||||||
return (dtNow > dtNext.AddDays(-14)) ? "the-bad" : "the-good";
|
return (dtNow > dtNext.AddDays(-14)) ? "the-bad" : "the-good";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@ public class VatUtils
|
||||||
// https://ec.europa.eu/taxation_customs/vies/faqvies.do#item_11
|
// https://ec.europa.eu/taxation_customs/vies/faqvies.do#item_11
|
||||||
// https://ec.europa.eu/taxation_customs/vies/
|
// https://ec.europa.eu/taxation_customs/vies/
|
||||||
|
|
||||||
public bool ValidateFormat(string countryCode, string vatNumber)
|
public static bool ValidateFormat(string countryCode, string vatNumber)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(vatNumber) || string.IsNullOrWhiteSpace(countryCode))
|
if (string.IsNullOrWhiteSpace(vatNumber) || string.IsNullOrWhiteSpace(countryCode))
|
||||||
return false;
|
return false;
|
||||||
|
@ -19,7 +19,7 @@ public class VatUtils
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateFormatDk(string vatNumber)
|
private static bool ValidateFormatDk(string vatNumber)
|
||||||
{
|
{
|
||||||
// https://wiki.scn.sap.com/wiki/display/CRM/Denmark
|
// https://wiki.scn.sap.com/wiki/display/CRM/Denmark
|
||||||
// 8 digits 0 to 9
|
// 8 digits 0 to 9
|
||||||
|
@ -35,7 +35,7 @@ public class VatUtils
|
||||||
return ValidateMod11(vatToCheck);
|
return ValidateMod11(vatToCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateFormatNo(string vatNumber)
|
private static bool ValidateFormatNo(string vatNumber)
|
||||||
{
|
{
|
||||||
// https://wiki.scn.sap.com/wiki/display/CRM/Norway
|
// https://wiki.scn.sap.com/wiki/display/CRM/Norway
|
||||||
// 12 digits
|
// 12 digits
|
||||||
|
@ -48,7 +48,7 @@ public class VatUtils
|
||||||
return long.Parse(vatToCheck) != 0 && ValidateMod11(vatNumber);
|
return long.Parse(vatToCheck) != 0 && ValidateMod11(vatNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateFormatSe(string vatNumber)
|
private static bool ValidateFormatSe(string vatNumber)
|
||||||
{
|
{
|
||||||
// https://wiki.scn.sap.com/wiki/display/CRM/Sweden
|
// https://wiki.scn.sap.com/wiki/display/CRM/Sweden
|
||||||
// 12 digits 0 to 9
|
// 12 digits 0 to 9
|
||||||
|
@ -73,7 +73,7 @@ public class VatUtils
|
||||||
return $"{vatToCheck[..9]}{c10}01" == vatNumber;
|
return $"{vatToCheck[..9]}{c10}01" == vatNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateMod11(string number)
|
private static bool ValidateMod11(string number)
|
||||||
{
|
{
|
||||||
if (long.Parse(number) == 0)
|
if (long.Parse(number) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -87,7 +87,7 @@ public class VatUtils
|
||||||
return sum % 11 == 0;
|
return sum % 11 == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string SanitizeVatNumber(string vatNumber)
|
private static string SanitizeVatNumber(string vatNumber)
|
||||||
{
|
{
|
||||||
vatNumber = vatNumber.ToUpperInvariant();
|
vatNumber = vatNumber.ToUpperInvariant();
|
||||||
return vatNumber
|
return vatNumber
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Blazored.LocalStorage;
|
||||||
using Blazored.Toast.Services;
|
using Blazored.Toast.Services;
|
||||||
using Wonky.Client.Services;
|
using Wonky.Client.Services;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
@ -31,16 +32,19 @@ namespace Wonky.Client.HttpInterceptors
|
||||||
private readonly IToastService _toast;
|
private readonly IToastService _toast;
|
||||||
private readonly RefreshTokenService _refreshTokenService;
|
private readonly RefreshTokenService _refreshTokenService;
|
||||||
private ILogger<HttpInterceptorService> _logger;
|
private ILogger<HttpInterceptorService> _logger;
|
||||||
|
private ILocalStorageService _storage;
|
||||||
|
|
||||||
public HttpInterceptorService(HttpClientInterceptor interceptor,
|
public HttpInterceptorService(HttpClientInterceptor interceptor,
|
||||||
NavigationManager navigation, IToastService toast,
|
NavigationManager navigation, IToastService toast,
|
||||||
RefreshTokenService refreshTokenService, ILogger<HttpInterceptorService> logger)
|
RefreshTokenService refreshTokenService, ILogger<HttpInterceptorService> logger,
|
||||||
|
ILocalStorageService storage)
|
||||||
{
|
{
|
||||||
_interceptor = interceptor;
|
_interceptor = interceptor;
|
||||||
_navigation = navigation;
|
_navigation = navigation;
|
||||||
_toast = toast;
|
_toast = toast;
|
||||||
_refreshTokenService = refreshTokenService;
|
_refreshTokenService = refreshTokenService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_storage = storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterEvent()
|
public void RegisterEvent()
|
||||||
|
@ -66,13 +70,11 @@ namespace Wonky.Client.HttpInterceptors
|
||||||
{
|
{
|
||||||
// call TryRefreshToken
|
// call TryRefreshToken
|
||||||
var token = await _refreshTokenService.TryRefreshToken();
|
var token = await _refreshTokenService.TryRefreshToken();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(token))
|
if (!string.IsNullOrEmpty(token))
|
||||||
{
|
{
|
||||||
// set new token
|
// set new token
|
||||||
e.Request.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
|
e.Request.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,15 +90,17 @@ namespace Wonky.Client.HttpInterceptors
|
||||||
{
|
{
|
||||||
case HttpStatusCode.NotFound:
|
case HttpStatusCode.NotFound:
|
||||||
//_navigation.NavigateTo("/404");
|
//_navigation.NavigateTo("/404");
|
||||||
message = "404 - Siden blev ikke fundet.";
|
message = "Der er ingen data ...";
|
||||||
_toast.ShowInfo(message);
|
_toast.ShowInfo(message);
|
||||||
break;
|
break;
|
||||||
case HttpStatusCode.BadRequest:
|
case HttpStatusCode.BadRequest:
|
||||||
|
ClearInfo();
|
||||||
_navigation.NavigateTo($"/login/{currDoc}");
|
_navigation.NavigateTo($"/login/{currDoc}");
|
||||||
message = "Verifikation nødvendig ...";
|
message = "Verifikation nødvendig ...";
|
||||||
_toast.ShowInfo(message);
|
_toast.ShowInfo(message);
|
||||||
break;
|
break;
|
||||||
case HttpStatusCode.Unauthorized:
|
case HttpStatusCode.Unauthorized:
|
||||||
|
ClearInfo();
|
||||||
_navigation.NavigateTo($"/login/{currDoc}");
|
_navigation.NavigateTo($"/login/{currDoc}");
|
||||||
message = "Verifikation nødvendig ...";
|
message = "Verifikation nødvendig ...";
|
||||||
_toast.ShowInfo(message);
|
_toast.ShowInfo(message);
|
||||||
|
@ -107,6 +111,11 @@ namespace Wonky.Client.HttpInterceptors
|
||||||
}
|
}
|
||||||
throw new HttpResponseException(message);
|
throw new HttpResponseException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void ClearInfo()
|
||||||
|
{
|
||||||
|
await _storage.RemoveItemsAsync(new List<string> {"_xa", "_xr", "_xe", "_xu"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class ActivityHttpRepository : IActivityHttpRepository
|
||||||
{
|
{
|
||||||
var response = await _client
|
var response = await _client
|
||||||
.GetAsync($"{_apiConfig.ActivityEndpoint}/date/{activityDate}")
|
.GetAsync($"{_apiConfig.ActivityEndpoint}/date/{activityDate}")
|
||||||
.ConfigureAwait(true);
|
;
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
//Console.WriteLine(content);
|
//Console.WriteLine(content);
|
||||||
return string.IsNullOrWhiteSpace(content)
|
return string.IsNullOrWhiteSpace(content)
|
||||||
|
@ -91,7 +91,7 @@ public class ActivityHttpRepository : IActivityHttpRepository
|
||||||
public async Task<ActivityResponseView> CreateActivity(ActivityDto model)
|
public async Task<ActivityResponseView> CreateActivity(ActivityDto model)
|
||||||
{
|
{
|
||||||
Console.WriteLine(JsonSerializer.Serialize(model));
|
Console.WriteLine(JsonSerializer.Serialize(model));
|
||||||
var response = await _client.PostAsJsonAsync($"{_apiConfig.ActivityEndpoint}", model).ConfigureAwait(true);
|
var response = await _client.PostAsJsonAsync($"{_apiConfig.ActivityEndpoint}", model);
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
var result = JsonSerializer.Deserialize<ActivityResponseView>(content);
|
var result = JsonSerializer.Deserialize<ActivityResponseView>(content);
|
||||||
return result!;
|
return result!;
|
||||||
|
@ -100,14 +100,14 @@ public class ActivityHttpRepository : IActivityHttpRepository
|
||||||
public async Task<ActivityDto> GetActivity(string id)
|
public async Task<ActivityDto> GetActivity(string id)
|
||||||
{
|
{
|
||||||
var salesItem = await _client
|
var salesItem = await _client
|
||||||
.GetFromJsonAsync<ActivityDto>($"{_apiConfig.ActivityEndpoint}/{id}").ConfigureAwait(true);
|
.GetFromJsonAsync<ActivityDto>($"{_apiConfig.ActivityEndpoint}/{id}");
|
||||||
return salesItem ?? new ActivityDto();
|
return salesItem ?? new ActivityDto();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ActivityResponseView> AcceptOffer(string id)
|
public async Task<ActivityResponseView> AcceptOffer(string id)
|
||||||
{
|
{
|
||||||
var response = await _client.PostAsJsonAsync($"{_apiConfig.ActivityEndpoint}/{id}/accept", id)
|
var response = await _client.PostAsJsonAsync($"{_apiConfig.ActivityEndpoint}/{id}/accept", id)
|
||||||
.ConfigureAwait(true);
|
;
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
var result = JsonSerializer.Deserialize<ActivityResponseView>(content);
|
var result = JsonSerializer.Deserialize<ActivityResponseView>(content);
|
||||||
return result!;
|
return result!;
|
||||||
|
|
|
@ -27,6 +27,7 @@ using Microsoft.Extensions.Options;
|
||||||
using Wonky.Entity.Configuration;
|
using Wonky.Entity.Configuration;
|
||||||
using Wonky.Entity.DTO;
|
using Wonky.Entity.DTO;
|
||||||
using Wonky.Entity.Requests;
|
using Wonky.Entity.Requests;
|
||||||
|
using Wonky.Entity.Views;
|
||||||
|
|
||||||
#pragma warning disable CS8601
|
#pragma warning disable CS8601
|
||||||
|
|
||||||
|
@ -90,22 +91,23 @@ public class CompanyHttpRepository : ICompanyHttpRepository
|
||||||
return company ?? new CompanyDto();
|
return company ?? new CompanyDto();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> CreateCompany(CompanyDto companyDto)
|
public async Task<string> CreateCompany(CompanyDto model)
|
||||||
{
|
{
|
||||||
var response = await _client.PostAsJsonAsync($"{_apiConfig.CustomerEndpoint}", companyDto);
|
var response = await _client.PostAsJsonAsync($"{_apiConfig.CustomerEndpoint}", model);
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
var result = JsonSerializer.Deserialize<CompanyDto>(content);
|
var result = JsonSerializer.Deserialize<CompanyDto>(content);
|
||||||
Console.WriteLine(content);
|
|
||||||
return result.CompanyId;
|
return result.CompanyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdateCompany(CompanyDto companyDto)
|
public async Task<bool> UpdateCompany(string companyId, CompanyDto model)
|
||||||
{
|
{
|
||||||
await _client.PutAsJsonAsync($"{_apiConfig.CustomerEndpoint}/{companyDto.CompanyId}", companyDto);
|
var response = await _client.PutAsJsonAsync($"{_apiConfig.CustomerEndpoint}/{companyId}", model);
|
||||||
|
return response.IsSuccessStatusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteCompany(string companyId)
|
public async Task<bool> DeleteCompany(string companyId)
|
||||||
{
|
{
|
||||||
await _client.DeleteAsync($"{_apiConfig.CustomerEndpoint}/{companyId}");
|
var response = await _client.DeleteAsync($"{_apiConfig.CustomerEndpoint}/{companyId}");
|
||||||
|
return response.IsSuccessStatusCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,6 +17,7 @@ using System.Threading.Tasks;
|
||||||
using Wonky.Client.Features;
|
using Wonky.Client.Features;
|
||||||
using Wonky.Entity.DTO;
|
using Wonky.Entity.DTO;
|
||||||
using Wonky.Entity.Requests;
|
using Wonky.Entity.Requests;
|
||||||
|
using Wonky.Entity.Views;
|
||||||
|
|
||||||
namespace Wonky.Client.HttpRepository;
|
namespace Wonky.Client.HttpRepository;
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ public interface ICompanyHttpRepository
|
||||||
Task<PagingResponse<CompanyDto>> GetCompaniesPaged(CompanyPagingParams pagingParameters);
|
Task<PagingResponse<CompanyDto>> GetCompaniesPaged(CompanyPagingParams pagingParameters);
|
||||||
Task<CompanyDto> GetCompanyByAccount(string accountNumber);
|
Task<CompanyDto> GetCompanyByAccount(string accountNumber);
|
||||||
Task<CompanyDto> GetCompanyById(string companyId);
|
Task<CompanyDto> GetCompanyById(string companyId);
|
||||||
Task<string> CreateCompany(CompanyDto companyDto);
|
Task<string> CreateCompany(CompanyDto model);
|
||||||
Task UpdateCompany(CompanyDto companyDto);
|
Task<bool> UpdateCompany(string companyId, CompanyDto model);
|
||||||
Task DeleteCompany(string companyId);
|
Task<bool> DeleteCompany(string companyId);
|
||||||
}
|
}
|
|
@ -4,7 +4,7 @@ namespace Wonky.Client.Models;
|
||||||
|
|
||||||
public class VatAddress
|
public class VatAddress
|
||||||
{
|
{
|
||||||
[Required] public string StreetName { get; set; } = "";
|
[Required(ErrorMessage = "Vejnavn skal angives")] public string StreetName { get; set; } = "";
|
||||||
[Required] public string HouseNumber { get; set; } = "";
|
[Required(ErrorMessage = "Husnummer skal angives")] public string HouseNumber { get; set; } = "";
|
||||||
[Required] public string ZipCode { get; set; } = "";
|
[Required(ErrorMessage = "Postnr skal angives")] public string ZipCode { get; set; } = "";
|
||||||
}
|
}
|
|
@ -18,131 +18,174 @@
|
||||||
@page "/company/create"
|
@page "/company/create"
|
||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
@using Wonky.Client.Components
|
@using Wonky.Client.Components
|
||||||
|
@using System.Xml
|
||||||
@attribute [Authorize(Roles = "Adviser")]
|
@attribute [Authorize(Roles = "Adviser")]
|
||||||
|
|
||||||
<h2>Opret firma</h2>
|
<h2>Opret kunde</h2>
|
||||||
<div class="card bg-light mb-2">
|
<table class="table">
|
||||||
<div class="card-header">
|
<thead>
|
||||||
CVR data
|
<tr>
|
||||||
</div>
|
<th colspan="2">Virksomhedsopslag</th>
|
||||||
<div class="card-body">
|
</tr>
|
||||||
<VatNumberInputComponent OnValidSubmit="GetInfoFromVat"/>
|
<tr>
|
||||||
</div>
|
<th>Reg.nr.</th>
|
||||||
<div class="card-body">
|
<th>Adresse</th>
|
||||||
<VatAddressInputComponent OnValidSubmit="GetInfoFromAddress"/>
|
</tr>
|
||||||
</div>
|
</thead>
|
||||||
@if (VInfos.Any())
|
<tbody>
|
||||||
{
|
<tr>
|
||||||
<div class="card-body">
|
<td class="align-middle">
|
||||||
@foreach (var info in VInfos)
|
<VatNumberInputComponent OnValidSubmit="GetInfoFromVat"/>
|
||||||
|
</td>
|
||||||
|
@if (_countryCode == "dk")
|
||||||
{
|
{
|
||||||
<div class="row mb-2">
|
<td class="align-middle">
|
||||||
<div class="col">
|
<VatAddressInputComponent Address="_vatAddress" OnValidSubmit="GetInfoFromAddress"/>
|
||||||
@info.VatNumber
|
</td>
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
@info.Name
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
@info.States[^1].State
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<button class="btn btn-primary" @onclick="@(() => SelectCompany(info.VatNumber))">OVERFØR</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
</div>
|
</tr>
|
||||||
|
@if (_vInfos.Any())
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">CVR ORG</th>
|
||||||
|
<th scope="col">Navn</th>
|
||||||
|
<th scope="col">Status</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach (var info in _vInfos)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td class="align-middle">@info.VatNumber</td>
|
||||||
|
<td class="align-middle">@info.Name</td>
|
||||||
|
<td class="align-middle">@info.States[^1].State</td>
|
||||||
|
<td class="align-middle"></td>
|
||||||
|
<td class="align-middle"><button class="btn btn-primary" @onclick="@(() => SelectCompany(info.VatNumber))">OVERFØR</button></td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
}
|
}
|
||||||
</div>
|
</tbody>
|
||||||
<div class="card bg-light">
|
</table>
|
||||||
<EditForm EditContext="_createCompany" OnValidSubmit="Create" class="card-body">
|
|
||||||
|
<EditForm EditContext="_createCompany" OnValidSubmit="Create">
|
||||||
<DataAnnotationsValidator />
|
<DataAnnotationsValidator />
|
||||||
<InputText type="hidden" id="salesRepId" @bind-Value="_companyDto.SalesRepId"/>
|
<InputText type="hidden" id="salesRepId" @bind-Value="_createDto.SalesRepId"/>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Besøgt
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Næste besøg
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Interval (uger)
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Reg.nr.</th>
|
|
||||||
<td class="state"><DisplayStateComponent StateClass="@RegState"></DisplayStateComponent></td>
|
|
||||||
<td>
|
<td>
|
||||||
<InputText id="vatNumber" class="form-control" @bind-Value="_companyDto.VatNumber"/>
|
<InputDate id="lastVisit" class="form-control" @bind-Value="@_lastVisit"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Firmanavn</th>
|
|
||||||
<td></td>
|
|
||||||
<td>
|
<td>
|
||||||
<InputText id="name" class="form-control" @bind-Value="_companyDto.Name"/>
|
<InputDate id="nextVisit" class="form-control" @bind-Value="@(_nextVisit)"/>
|
||||||
<ValidationMessage For="@(() => _companyDto.Name)"></ValidationMessage>
|
<ValidationMessage For="@(() => _createDto.NextVisit)"></ValidationMessage>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Adresse</th>
|
|
||||||
<td></td>
|
|
||||||
<td>
|
<td>
|
||||||
<InputText id="address1" class="form-control" @bind-Value="_companyDto.Address1"/>
|
<InputNumber id="interval" class="form-control" @bind-Value="_createDto.Interval"/>
|
||||||
</td>
|
<ValidationMessage For="@(() => _createDto.Interval)"></ValidationMessage>
|
||||||
</tr>
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<th scope="row">Conavn</th>
|
</tbody>
|
||||||
<td></td>
|
</table>
|
||||||
<td>
|
<table class="table">
|
||||||
<InputText id="address2" class="form-control" @bind-Value="_companyDto.Address2"/>
|
<thead>
|
||||||
</td>
|
<tr>
|
||||||
</tr>
|
<th colspan="5">
|
||||||
<tr>
|
Stamdata
|
||||||
<th scope="row">Postnr</th>
|
</th>
|
||||||
<td></td>
|
</tr>
|
||||||
<td>
|
</thead>
|
||||||
<InputText id="zipCode" class="form-control" @bind-Value="_companyDto.ZipCode"/>
|
<tbody>
|
||||||
<ValidationMessage For="@(() => _companyDto.ZipCode)"></ValidationMessage>
|
<tr>
|
||||||
</td>
|
<td class="align-middle">Reg.nr.</td>
|
||||||
</tr>
|
<td class="align-middle state"><DisplayStateComponent StateClass="@RegState"></DisplayStateComponent></td>
|
||||||
<tr>
|
<td class="align-middle">
|
||||||
<th scope="row">Bynavn</th>
|
<InputText id="vatNumber" class="form-control" @bind-Value="_createDto.VatNumber"/>
|
||||||
<td></td>
|
</td>
|
||||||
<td>
|
<td class="align-middle">Telefon</td>
|
||||||
<InputText id="city" class="form-control" @bind-Value="_companyDto.City"/>
|
<td class="align-middle">
|
||||||
<ValidationMessage For="@(() => _companyDto.City)"></ValidationMessage>
|
<InputText id="phone" class="form-control" @bind-Value="_createDto.Phone"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Telefon</th>
|
<td class="align-middle">Firmanavn</td>
|
||||||
<td></td>
|
<td class="align-middle"></td>
|
||||||
<td>
|
<td colspan="3">
|
||||||
<InputText id="phone" class="form-control" @bind-Value="_companyDto.Phone"/>
|
<InputText id="name" class="form-control" @bind-Value="_createDto.Name"/>
|
||||||
</td>
|
<ValidationMessage For="@(() => _createDto.Name)"></ValidationMessage>
|
||||||
</tr>
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<th scope="row">Mobil</th>
|
<tr>
|
||||||
<td></td>
|
<td class="align-middle">Attention</td>
|
||||||
<td>
|
<td class="align-middle"></td>
|
||||||
<InputText id="mobile" class="form-control" @bind-Value="_companyDto.Mobile"/>
|
<td colspan="3">
|
||||||
</td>
|
<InputText id="attention" class="form-control" @bind-Value="_createDto.Attention"/>
|
||||||
</tr>
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<th scope="row">Email</th>
|
<tr>
|
||||||
<td></td>
|
<td class="align-middle">Adresse</td>
|
||||||
<td>
|
<td class="align-middle"></td>
|
||||||
<InputText id="email" class="form-control" @bind-Value="_companyDto.Email"/>
|
<td class="align-middle">
|
||||||
</td>
|
<InputText id="address1" class="form-control" @bind-Value="_createDto.Address1"/>
|
||||||
</tr>
|
</td>
|
||||||
<tr>
|
<td class="align-middle">Adresse</td>
|
||||||
<th scope="row">Attention</th>
|
<td class="align-middle">
|
||||||
<td></td>
|
<InputText id="address2" class="form-control" @bind-Value="_createDto.Address2"/>
|
||||||
<td>
|
</td>
|
||||||
<InputText id="attention" class="form-control" @bind-Value="_companyDto.Attention"/>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="align-middle">Postnr</td>
|
||||||
|
<td class="align-middle"></td>
|
||||||
|
<td class="align-middle">
|
||||||
|
<InputText id="zipCode" class="form-control" @bind-Value="_createDto.ZipCode"/>
|
||||||
|
<ValidationMessage For="@(() => _createDto.ZipCode)"></ValidationMessage>
|
||||||
|
</td>
|
||||||
|
<td class="align-middle">Bynavn</td>
|
||||||
|
<td class="align-middle">
|
||||||
|
<InputText id="city" class="form-control" @bind-Value="_createDto.City"/>
|
||||||
|
<ValidationMessage For="@(() => _createDto.City)"></ValidationMessage>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="align-middle">Mobil</td>
|
||||||
|
<td class="align-middle"></td>
|
||||||
|
<td class="align-middle">
|
||||||
|
<InputText id="mobile" class="form-control" @bind-Value="_createDto.Mobile"/>
|
||||||
|
</td>
|
||||||
|
<td class="align-middle">Email</td>
|
||||||
|
<td class="align-middle">
|
||||||
|
<InputText id="email" class="form-control" @bind-Value="_createDto.Email"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<div class="col-md-12 text-right">
|
<div class="col-md-8"></div>
|
||||||
|
<div class="col-md-4">
|
||||||
<button type="submit" class="btn btn-success" disabled="@_formInvalid">Opret</button>
|
<button type="submit" class="btn btn-success" disabled="@_formInvalid">Opret</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</EditForm>
|
</EditForm>
|
||||||
</div>
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ using Microsoft.AspNetCore.Components.Forms;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Wonky.Client.Helpers;
|
using Wonky.Client.Helpers;
|
||||||
using Wonky.Client.Models;
|
using Wonky.Client.Models;
|
||||||
|
using Wonky.Client.Shared;
|
||||||
using Wonky.Entity.DTO;
|
using Wonky.Entity.DTO;
|
||||||
using Wonky.Entity.Models;
|
using Wonky.Entity.Models;
|
||||||
using Wonky.Entity.Requests;
|
using Wonky.Entity.Requests;
|
||||||
|
@ -43,77 +44,92 @@ namespace Wonky.Client.Pages
|
||||||
[Inject] public ICompanyHttpRepository CompanyRepo { get; set; }
|
[Inject] public ICompanyHttpRepository CompanyRepo { get; set; }
|
||||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||||
[Inject] public VatInfoLookupService VatInfoLookupService { get; set; }
|
[Inject] public VatInfoLookupService VatInfoLookupService { get; set; }
|
||||||
private List<VirkRegInfo> VInfos { get; set; } = new();
|
private List<VirkRegInfo> _vInfos { get; set; } = new();
|
||||||
private CompanyDto _companyDto = new();
|
private CompanyDto _createDto = new();
|
||||||
private VirkRegInfo _virkRegInfo = new();
|
private VirkRegInfo _virkRegInfo = new();
|
||||||
private EditContext _createCompany;
|
private EditContext _createCompany;
|
||||||
private bool _formInvalid = true;
|
private bool _formInvalid = true;
|
||||||
private VatUtils _vatUtils { get; set; }
|
private VatAddress _vatAddress = new();
|
||||||
private string RegState { get; set; } = "";
|
private string RegState = "";
|
||||||
|
private DateTime _lastVisit { get; set; }
|
||||||
|
private DateTime _nextVisit { get; set; }
|
||||||
|
private string _countryCode;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
_vatUtils = new VatUtils();
|
|
||||||
_createCompany = new EditContext(_companyDto);
|
|
||||||
_createCompany.OnFieldChanged += HandleFieldChanged;
|
|
||||||
|
|
||||||
var ux = await StorageService.GetItemAsync<UserInfoView>("_xu");
|
|
||||||
_companyDto.SalesRepId = ux.Id;
|
|
||||||
_companyDto.CountryCode = ux.CountryCode;
|
|
||||||
Interceptor.RegisterEvent();
|
Interceptor.RegisterEvent();
|
||||||
Interceptor.RegisterBeforeSendEvent();
|
Interceptor.RegisterBeforeSendEvent();
|
||||||
|
|
||||||
|
var ux = await StorageService.GetItemAsync<UserInfoView>("_xu");
|
||||||
|
_countryCode = ux.CountryCode;
|
||||||
|
_createDto.SalesRepId = ux.Id;
|
||||||
|
_createDto.CountryCode = ux.CountryCode;
|
||||||
|
_lastVisit = DateTime.Now;
|
||||||
|
_nextVisit = DateTime.Now.AddDays(_createDto.Interval * 7);
|
||||||
|
_createDto.LastVisit = $"{_lastVisit:yyyy-MM-dd}";
|
||||||
|
_createDto.LastVisit = $"{_nextVisit:yyyy-MM-dd}";
|
||||||
|
_createCompany = new EditContext(_createDto);
|
||||||
|
_createCompany.OnFieldChanged += HandleFieldChanged;
|
||||||
|
_createCompany.OnValidationStateChanged += ValidationChanged;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task GetInfoFromAddress(VatAddress address)
|
private async Task GetInfoFromAddress(VatAddress address)
|
||||||
{
|
{
|
||||||
VInfos = await VatInfoLookupService.QueryVirkRegistry(
|
ToastService.ShowInfo("Vent for adresse info ...");
|
||||||
|
_vInfos = await VatInfoLookupService.QueryVirkRegistry(
|
||||||
new VirkParams
|
new VirkParams
|
||||||
{
|
{
|
||||||
StreetName = address.StreetName,
|
StreetName = address.StreetName,
|
||||||
HouseNumber = address.HouseNumber,
|
HouseNumber = address.HouseNumber,
|
||||||
ZipCode = address.ZipCode
|
ZipCode = address.ZipCode
|
||||||
});
|
});
|
||||||
if (!VInfos.Any())
|
if (!_vInfos.Any())
|
||||||
{
|
{
|
||||||
ToastService.ShowError($"Ingen virksomheder fundet.");
|
ToastService.ShowInfo($"Ingen data fundet ...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private async Task GetInfoFromVat(string vatNumber)
|
private async Task GetInfoFromVat(string vatNumber)
|
||||||
{
|
{
|
||||||
VInfos = await VatInfoLookupService
|
ToastService.ShowInfo("Vent for firma info ...");
|
||||||
|
_vInfos = await VatInfoLookupService
|
||||||
.QueryVirkRegistry(new VirkParams {VatNumber = vatNumber});
|
.QueryVirkRegistry(new VirkParams {VatNumber = vatNumber});
|
||||||
if (!VInfos.Any())
|
if (!_vInfos.Any())
|
||||||
{
|
{
|
||||||
ToastService.ShowError($"Firma med CVR '{vatNumber}' findes ikke.");
|
ToastService.ShowError($"Firma med CVR '{vatNumber}' findes ikke.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
ToastService.ShowSuccess($"Data for '{vatNumber}' er hentet.");
|
|
||||||
//SelectCompany(vatNumber);
|
|
||||||
}
|
}
|
||||||
private void SelectCompany(string vatNumber)
|
private void SelectCompany(string vatNumber)
|
||||||
{
|
{
|
||||||
_virkRegInfo = (from x in VInfos where x.VatNumber == vatNumber select x).First();
|
_virkRegInfo = (from x in _vInfos where x.VatNumber == vatNumber select x).First();
|
||||||
RegState = _virkRegInfo.States[^1].State == "NORMAL" ? "the-good" : "the-ugly";
|
RegState = _virkRegInfo.States[^1].State == "NORMAL" ? "the-good" : "the-ugly";
|
||||||
_companyDto.Name = _virkRegInfo.Name;
|
_createDto.Name = _virkRegInfo.Name;
|
||||||
_companyDto.Address1 = _virkRegInfo.Address;
|
_createDto.Address1 = _virkRegInfo.CoName;
|
||||||
_companyDto.Address2 = _virkRegInfo.CoName;
|
_createDto.Address2 = _virkRegInfo.Address;
|
||||||
_companyDto.ZipCode = _virkRegInfo.ZipCode;
|
_createDto.ZipCode = _virkRegInfo.ZipCode;
|
||||||
_companyDto.City = _virkRegInfo.City;
|
_createDto.City = _virkRegInfo.City;
|
||||||
_companyDto.VatNumber = _virkRegInfo.VatNumber;
|
_createDto.VatNumber = _virkRegInfo.VatNumber;
|
||||||
|
_createDto.ValidVat = 1;
|
||||||
}
|
}
|
||||||
private async Task Create()
|
private async Task Create()
|
||||||
{
|
{
|
||||||
var newId = await CompanyRepo.CreateCompany(_companyDto);
|
var newId = await CompanyRepo.CreateCompany(_createDto);
|
||||||
Console.WriteLine(newId);
|
if (!string.IsNullOrWhiteSpace(newId))
|
||||||
ToastService.ShowSuccess($"Godt så! '{_companyDto.Name}' er oprettet i CRM.");
|
{
|
||||||
Navigation.NavigateTo($"/company/id/{newId}");
|
ToastService.ShowSuccess($"'{_createDto.Name}' er oprettet i CRM.");
|
||||||
|
Navigation.NavigateTo($"/company/id/{newId}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (!_vatUtils.ValidateFormat(_companyDto.CountryCode, _companyDto.VatNumber))
|
_createDto.LastVisit = $"{_lastVisit:yyyy-MM-dd}";
|
||||||
|
_createDto.NextVisit = $"{_nextVisit:yyyy-MM-dd}";
|
||||||
|
|
||||||
|
if (!VatUtils.ValidateFormat(_createDto.CountryCode, _createDto.VatNumber)
|
||||||
|
|| !_createDto.ValidDateSpan())
|
||||||
{
|
{
|
||||||
_formInvalid = false;
|
_formInvalid = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -124,8 +140,11 @@ namespace Wonky.Client.Pages
|
||||||
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
||||||
{
|
{
|
||||||
_formInvalid = true;
|
_formInvalid = true;
|
||||||
|
|
||||||
_createCompany.OnFieldChanged -= HandleFieldChanged;
|
_createCompany.OnFieldChanged -= HandleFieldChanged;
|
||||||
_createCompany = new EditContext(_companyDto);
|
|
||||||
|
_createCompany = new EditContext(_createDto);
|
||||||
|
|
||||||
_createCompany.OnFieldChanged += HandleFieldChanged;
|
_createCompany.OnFieldChanged += HandleFieldChanged;
|
||||||
_createCompany.OnValidationStateChanged -= ValidationChanged;
|
_createCompany.OnValidationStateChanged -= ValidationChanged;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,147 +21,161 @@
|
||||||
@attribute [Authorize(Roles = "Adviser")]
|
@attribute [Authorize(Roles = "Adviser")]
|
||||||
@page "/company/{CompanyId}/update"
|
@page "/company/{CompanyId}/update"
|
||||||
|
|
||||||
@if (CompanyDto != null)
|
@if (!string.IsNullOrWhiteSpace(_companyView.Name))
|
||||||
{
|
{
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="h2">@CompanyDto.Account - @CompanyDto.Name</div>
|
<h5>@_companyView.Account - @_companyView.Name</h5>
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<VatNumberInputComponent OnValidSubmit="GetInfoFromVat"/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<VatAddressInputComponent Address="vatAddress" OnValidSubmit="GetInfoFromAddress"/>
|
<VatAddressInputComponent Address="vatAddress" OnValidSubmit="GetInfoFromAddress"/>
|
||||||
</div>
|
</div>
|
||||||
@if (VInfos.Any())
|
@if (_vInfos.Any())
|
||||||
{
|
{
|
||||||
<div class="card-body">
|
<table class="table">
|
||||||
@foreach (var info in VInfos)
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">CVR ORG</th>
|
||||||
|
<th scope="col">Navn</th>
|
||||||
|
<th scope="col">Status</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach (var info in _vInfos)
|
||||||
{
|
{
|
||||||
<div class="row mb-1">
|
<tr>
|
||||||
<div class="col">
|
<td class="align-middle">@info.VatNumber</td>
|
||||||
@info.VatNumber
|
<td class="align-middle">@info.Name</td>
|
||||||
</div>
|
<td class="align-middle">@info.States[^1].State</td>
|
||||||
<div class="col">
|
<td class="align-middle">
|
||||||
@info.Name
|
<button class="btn btn-primary" @onclick="@(() => SelectCompany(info.VatNumber, true))">OVERRØR</button>
|
||||||
</div>
|
</td>
|
||||||
<div class="col">
|
<td class="align-middle">
|
||||||
@info.States[^1].State
|
<button class="btn btn-primary" @onclick="@(() => SelectCompany(info.VatNumber, false))">CVR/VAT</button>
|
||||||
</div>
|
</td>
|
||||||
<div class="col">
|
</tr>
|
||||||
<button class="btn btn-primary" @onclick="@(() => SelectCompany(info.VatNumber))">OVERFØR</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
</div>
|
</tbody>
|
||||||
|
</table>
|
||||||
}
|
}
|
||||||
<div class="card-body">
|
<EditForm EditContext="_updateCompany" OnValidSubmit="SubmitUpdate">
|
||||||
<EditForm EditContext="_updateCompany" OnValidSubmit="Update">
|
<DataAnnotationsValidator/>
|
||||||
<DataAnnotationsValidator/>
|
<div class="card-body">
|
||||||
<div class="form-group row mb-1">
|
<div class="form-group row mb-1">
|
||||||
<label for="vatNumber" class="col-md-2 col-form-label">
|
<label for="vatNumber" class="col-md-2 col-form-label">
|
||||||
<DisplayStateComponent StateClass="@_vatState"></DisplayStateComponent>
|
<DisplayStateComponent StateClass="@_vatState"></DisplayStateComponent>
|
||||||
CVR/ORG
|
CVR/ORG
|
||||||
</label>
|
</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<InputText id="vatNumber" class="form-control" @bind-Value="CompanyDto.VatNumber"/>
|
<InputText id="vatNumber" class="form-control" @bind-Value="_companyView.VatNumber"/>
|
||||||
<ValidationMessage For="@(() => CompanyDto.VatNumber)"></ValidationMessage>
|
<ValidationMessage For="@(() => _companyView.VatNumber)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-1">
|
<div class="form-group row mb-1">
|
||||||
<label for="name" class="col-md-2 col-form-label">Firmanavn</label>
|
<label for="name" class="col-md-2 col-form-label">Firmanavn</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<InputText id="name" class="form-control" @bind-Value="CompanyDto.Name"/>
|
<InputText id="name" class="form-control" @bind-Value="_companyView.Name"/>
|
||||||
<ValidationMessage For="@(() => CompanyDto.Name)"></ValidationMessage>
|
<ValidationMessage For="@(() => _companyView.Name)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-1">
|
<div class="form-group row mb-1">
|
||||||
<label for="address1" class="col-md-2 col-form-label">Adresse</label>
|
<label for="address1" class="col-md-2 col-form-label">Adresse</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<InputText id="address1" class="form-control" @bind-Value="CompanyDto.Address1"/>
|
<InputText id="address1" class="form-control" @bind-Value="_companyView.Address1"/>
|
||||||
<ValidationMessage For="@(() => CompanyDto.Address1)"></ValidationMessage>
|
<ValidationMessage For="@(() => _companyView.Address1)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-1">
|
<div class="form-group row mb-1">
|
||||||
<label for="address2" class="col-md-2 col-form-label">Conavn</label>
|
<label for="address2" class="col-md-2 col-form-label">Adresse</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<InputText id="address2" class="form-control" @bind-Value="CompanyDto.Address2"/>
|
<InputText id="address2" class="form-control" @bind-Value="_companyView.Address2"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-1">
|
<div class="form-group row mb-1">
|
||||||
<label for="zipCode" class="col-md-2 col-form-label">Postnr</label>
|
<label for="zipCode" class="col-md-2 col-form-label">Postnr</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<InputText id="zipCode" class="form-control" @bind-Value="CompanyDto.ZipCode"/>
|
<InputText id="zipCode" class="form-control" @bind-Value="_companyView.ZipCode"/>
|
||||||
<ValidationMessage For="@(() => CompanyDto.ZipCode)"></ValidationMessage>
|
<ValidationMessage For="@(() => _companyView.ZipCode)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-1">
|
<div class="form-group row mb-1">
|
||||||
<label for="city" class="col-md-2 col-form-label">Bynavn</label>
|
<label for="city" class="col-md-2 col-form-label">Bynavn</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<InputText id="city" class="form-control" @bind-Value="CompanyDto.City"/>
|
<InputText id="city" class="form-control" @bind-Value="_companyView.City"/>
|
||||||
<ValidationMessage For="@(() => CompanyDto.City)"></ValidationMessage>
|
<ValidationMessage For="@(() => _companyView.City)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-1">
|
<div class="form-group row mb-1">
|
||||||
<label for="phone" class="col-md-2 col-form-label">Telefon</label>
|
<label for="phone" class="col-md-2 col-form-label">Telefon</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<InputText id="phone" class="form-control" @bind-Value="CompanyDto.Phone"/>
|
<InputText id="phone" class="form-control" @bind-Value="_companyView.Phone"/>
|
||||||
|
<ValidationMessage For="@(() => _companyView.Phone)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-1">
|
<div class="form-group row mb-1">
|
||||||
<label for="mobile" class="col-md-2 col-form-label">Mobil</label>
|
<label for="mobile" class="col-md-2 col-form-label">Mobil</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<InputText id="mobile" class="form-control" @bind-Value="CompanyDto.Mobile"/>
|
<InputText id="mobile" class="form-control" @bind-Value="_companyView.Mobile"/>
|
||||||
|
<ValidationMessage For="@(() => _companyView.Mobile)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-1">
|
<div class="form-group row mb-1">
|
||||||
<label for="email" class="col-md-2 col-form-label">Email</label>
|
<label for="email" class="col-md-2 col-form-label">Email</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<InputText id="email" class="form-control" @bind-Value="CompanyDto.Email"/>
|
<InputText id="email" class="form-control" @bind-Value="_companyView.Email"/>
|
||||||
|
<ValidationMessage For="@(() => _companyView.Email)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-1">
|
<div class="form-group row mb-1">
|
||||||
<label for="attention" class="col-md-2 col-form-label">Attention</label>
|
<label for="attention" class="col-md-2 col-form-label">Attention</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<InputText id="attention" class="form-control" @bind-Value="CompanyDto.Attention"/>
|
<InputText id="attention" class="form-control" @bind-Value="_companyView.Attention"/>
|
||||||
|
<ValidationMessage For="@(() => _companyView.Attention)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-1">
|
<div class="form-group row mb-1">
|
||||||
<label for="lastVisit" class="col-form-label col-md-2">
|
<label for="lastVisit" class="col-form-label col-md-2">
|
||||||
<DisplayStateComponent StateClass="@(_hasFolded ? "the-dead" : Utils.GetVisitState(CompanyDto.NextVisit))"></DisplayStateComponent>
|
<DisplayStateComponent
|
||||||
Sidste besøg
|
StateClass="@(_hasFolded ? "the-dead" : Utils.GetVisitState($"{_companyView.NextVisit}"))">
|
||||||
|
</DisplayStateComponent>
|
||||||
|
Besøgt
|
||||||
</label>
|
</label>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<InputDate id="lastVisit" class="form-control" @bind-Value="@LastVisit"/>
|
<InputDate id="lastVisit" class="form-control" @bind-Value="@_lastVisit"/>
|
||||||
</div>
|
</div>
|
||||||
<label for="nextVisit" class="col-form-label col-md-2">Næste besøg</label>
|
<label for="nextVisit" class="col-form-label col-md-2">Næste besøg</label>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<InputDate id="nextVisit" class="form-control" @bind-Value="@(NextVisit)"/>
|
<InputDate id="nextVisit" class="form-control" @bind-Value="@(_nextVisit)"/>
|
||||||
|
<ValidationMessage For="@(() => _companyView.NextVisit)">Dato kan ikke vær før sidste besøg</ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-1">
|
<div class="form-group row mb-1">
|
||||||
<label for="interval" class="col-form-label col-md-2">Interval (uger)</label>
|
<label for="interval" class="col-form-label col-md-2">Interval (uger)</label>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<InputNumber id="interval" class="form-control" @bind-Value="CompanyDto.Interval"/>
|
<InputNumber id="interval" class="form-control" @bind-Value="_companyView.Interval"/>
|
||||||
|
<ValidationMessage For="@(() => _companyView.Interval)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1">
|
|
||||||
<div class="col-sm-2 col-md-2 text-right">
|
|
||||||
<button type="button" class="btn btn-danger">SLET</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-2 col-md-2 text-right">
|
|
||||||
<button type="submit" class="btn btn-success">GEM</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</EditForm>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<a class="btn btn-primary" href="/company/@CompanyDto.CompanyId">Tilbage</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="card-footer">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-md-2">
|
||||||
|
<button type="button" class="btn btn-warning">SKJUL</button>
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-2">
|
||||||
|
<button type="button" class="btn btn-danger">SLET</button>
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-2">
|
||||||
|
<button type="submit" class="btn btn-success">GEM</button>
|
||||||
|
</div>
|
||||||
|
<div class="col col-md-2">
|
||||||
|
<a class="btn btn-primary" href="/company/@CompanyId">Tilbage</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</EditForm>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -43,137 +43,181 @@ public partial class CompanyUpdate : IDisposable
|
||||||
[Inject] public ILocalStorageService StorageService { get; set; }
|
[Inject] public ILocalStorageService StorageService { get; set; }
|
||||||
[Parameter] public string Account { get; set; } = "";
|
[Parameter] public string Account { get; set; } = "";
|
||||||
[Parameter] public string CompanyId { get; set; } = "";
|
[Parameter] public string CompanyId { get; set; } = "";
|
||||||
private CompanyDto CompanyDto { get; set; }
|
private CompanyDto _companyView { get; set; } = new();
|
||||||
private EditContext _updateCompany { get; set; }
|
private EditContext _updateCompany { get; set; }
|
||||||
private List<VirkRegInfo> VInfos { get; set; } = new();
|
private List<VirkRegInfo> _vInfos { get; set; } = new();
|
||||||
private VirkRegInfo _virkRegInfo { get; set; } = new();
|
private VirkRegInfo _virkRegInfo { get; set; } = new();
|
||||||
private DateTime LastVisit { get; set; }
|
private DateTime _lastVisit { get; set; }
|
||||||
private DateTime NextVisit { get; set; }
|
private DateTime _nextVisit { get; set; }
|
||||||
private string _vatState { get; set; } = "the-ugly";
|
private string _vatState { get; set; } = "the-ugly";
|
||||||
private VatUtils _vatUtils { get; set; }
|
|
||||||
private VatAddress vatAddress = new();
|
private VatAddress vatAddress = new();
|
||||||
private bool validVat;
|
private bool _validVat;
|
||||||
private bool _hasFolded;
|
private bool _hasFolded;
|
||||||
|
private bool _formInvalid = true;
|
||||||
|
private string _orgVat;
|
||||||
|
|
||||||
|
private readonly JsonSerializerOptions _options = new ()
|
||||||
|
{
|
||||||
|
PropertyNameCaseInsensitive = true
|
||||||
|
};
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
_vatUtils = new VatUtils();
|
|
||||||
Interceptor.RegisterEvent();
|
|
||||||
Interceptor.RegisterBeforeSendEvent();
|
|
||||||
CompanyDto = await CompanyRepo.GetCompanyById(CompanyId);
|
|
||||||
LastVisit = DateTime.Parse(CompanyDto.LastVisit);
|
|
||||||
NextVisit = DateTime.Parse(CompanyDto.NextVisit);
|
|
||||||
_updateCompany = new EditContext(CompanyDto);
|
|
||||||
var ux = await StorageService.GetItemAsync<UserInfoView>("_xu");
|
var ux = await StorageService.GetItemAsync<UserInfoView>("_xu");
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(CompanyDto.CountryCode))
|
Interceptor.RegisterEvent();
|
||||||
{
|
Interceptor.RegisterBeforeSendEvent();
|
||||||
CompanyDto.CountryCode = ux.CountryCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(CompanyDto.HasFolded == 1)
|
_companyView = await CompanyRepo.GetCompanyById(CompanyId);
|
||||||
|
_orgVat = _companyView.VatNumber;
|
||||||
|
_companyView.CountryCode = ux.CountryCode.ToLower();
|
||||||
|
|
||||||
|
vatAddress = PrepareVatAddress(_companyView);
|
||||||
|
|
||||||
|
if (_companyView.Interval == 0)
|
||||||
|
_companyView.Interval = 8;
|
||||||
|
|
||||||
|
_lastVisit = DateTime.Parse(_companyView.LastVisit);
|
||||||
|
_nextVisit = DateTime.Parse(_companyView.NextVisit);
|
||||||
|
|
||||||
|
if (!_companyView.ValidDateSpan())
|
||||||
|
_nextVisit = _lastVisit.AddDays(_companyView.Interval * 7);
|
||||||
|
|
||||||
|
if(_companyView.HasFolded == 1)
|
||||||
{
|
{
|
||||||
_hasFolded = true;
|
_hasFolded = true;
|
||||||
_vatState = "the-dead";
|
_vatState = "the-dead";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_vatState = _vatUtils.ValidateFormat(CompanyDto.CountryCode, CompanyDto.VatNumber) ? "the-good" : "the-draw";
|
if (_companyView.ValidVat == 0 && !string.IsNullOrWhiteSpace(_companyView.VatNumber))
|
||||||
|
_companyView.ValidVat = VatUtils.ValidateFormat(_companyView.CountryCode, _companyView.VatNumber) ? 1 : 0;
|
||||||
|
_validVat = _companyView.ValidVat == 1;
|
||||||
|
_vatState = _companyView.ValidVat == 1 ? "the-good" : "the-draw";
|
||||||
}
|
}
|
||||||
vatAddress = PrepareVatAddress();
|
_updateCompany = new EditContext(_companyView);
|
||||||
|
_updateCompany.OnFieldChanged += HandleFieldChanged;
|
||||||
|
_updateCompany.OnValidationStateChanged += ValidationChanged;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private VatAddress PrepareVatAddress()
|
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var digits = "123456789".ToCharArray();
|
_nextVisit = _lastVisit.AddDays(_companyView.Interval * 7);
|
||||||
var pos1 = CompanyDto.Address1.IndexOfAny(digits);
|
|
||||||
if (pos1 > 0)
|
_companyView.LastVisit = $"{_lastVisit:yyyy-MM-dd}";
|
||||||
|
_companyView.NextVisit = $"{_nextVisit:yyyy-MM-dd}";
|
||||||
|
|
||||||
|
if (!VatUtils.ValidateFormat(_companyView.CountryCode, _companyView.VatNumber) ||
|
||||||
|
!_companyView.ValidDateSpan())
|
||||||
{
|
{
|
||||||
return new VatAddress
|
_formInvalid = true;
|
||||||
{
|
|
||||||
ZipCode = CompanyDto.ZipCode,
|
|
||||||
StreetName = CompanyDto.Address1[..pos1],
|
|
||||||
HouseNumber = Regex.Replace(CompanyDto.Address1[pos1..], "[^0-9]", "")
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
var pos2 = CompanyDto.Address2.IndexOfAny(digits);
|
else
|
||||||
if (pos2 > 0)
|
|
||||||
{
|
{
|
||||||
return new VatAddress
|
_formInvalid = !_updateCompany.Validate();
|
||||||
{
|
|
||||||
ZipCode = CompanyDto.ZipCode,
|
|
||||||
StreetName = CompanyDto.Address2[..pos2],
|
|
||||||
HouseNumber = Regex.Replace(CompanyDto.Address2[pos2..], "[^0-9]", "")
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return vatAddress;
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
private async Task Update()
|
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(CompanyDto.VatNumber) && !_vatUtils.ValidateFormat(CompanyDto.CountryCode, CompanyDto.VatNumber))
|
_formInvalid = true;
|
||||||
|
_updateCompany.OnFieldChanged -= HandleFieldChanged;
|
||||||
|
|
||||||
|
_updateCompany = new EditContext(_companyView);
|
||||||
|
|
||||||
|
_updateCompany.OnFieldChanged += HandleFieldChanged;
|
||||||
|
_updateCompany.OnValidationStateChanged -= ValidationChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SubmitUpdate()
|
||||||
|
{
|
||||||
|
if (!VatUtils.ValidateFormat(_companyView.CountryCode, _companyView.VatNumber))
|
||||||
{
|
{
|
||||||
ToastService.ShowError($"CVR/VAT/ORG nummer er ugyldig.");
|
ToastService.ShowError($"CVR/VAT/ORG nummer er ugyldig.");
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CompanyDto.LastVisit = $"{LastVisit:yyyy-MM-dd}";
|
_companyView.LastVisit = $"{_lastVisit:yyyy-MM-dd}";
|
||||||
CompanyDto.NextVisit = $"{NextVisit:yyyy-MM-dd}";
|
_companyView.NextVisit = $"{_nextVisit:yyyy-MM-dd}";
|
||||||
|
_companyView.IsHidden = 0;
|
||||||
|
if (_companyView.VatNumber != _orgVat)
|
||||||
|
_companyView.UpdateErpVat = 1;
|
||||||
|
|
||||||
Console.WriteLine(JsonSerializer.Serialize(CompanyDto));
|
var x = JsonSerializer.Serialize(_companyView, _options);
|
||||||
|
Logger.LogInformation(x);
|
||||||
await CompanyRepo.UpdateCompany(CompanyDto);
|
var success = await CompanyRepo.UpdateCompany(CompanyId, _companyView );
|
||||||
|
if (success)
|
||||||
ToastService.ShowSuccess($"'{CompanyDto!.Name}' er opdateret.");
|
|
||||||
Navigation.NavigateTo($"/company/{CompanyDto.CompanyId}");
|
|
||||||
}
|
|
||||||
private async Task GetInfoFromVat(string vatNumber)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(vatNumber) || !_vatUtils.ValidateFormat(CompanyDto.CountryCode, CompanyDto.VatNumber))
|
|
||||||
{
|
{
|
||||||
ToastService.ShowError($"CVR er ugyldigt eller mangler");
|
ToastService.ShowSuccess("Check");
|
||||||
return;
|
Navigation.NavigateTo($"/company/{CompanyId}");
|
||||||
}
|
|
||||||
VInfos = await VatInfoLookupService
|
|
||||||
.QueryVirkRegistry(
|
|
||||||
new VirkParams
|
|
||||||
{
|
|
||||||
VatNumber = vatNumber.Trim()
|
|
||||||
});
|
|
||||||
if (string.IsNullOrWhiteSpace(VInfos[0].VatNumber))
|
|
||||||
{
|
|
||||||
ToastService.ShowError($"CVR nummer '{vatNumber}' findes ikke.");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task GetInfoFromAddress(VatAddress address)
|
private async Task GetInfoFromAddress(VatAddress address)
|
||||||
{
|
{
|
||||||
VInfos = await VatInfoLookupService.QueryVirkRegistry(
|
_vInfos = await VatInfoLookupService.QueryVirkRegistry(
|
||||||
new VirkParams
|
new VirkParams
|
||||||
{
|
{
|
||||||
StreetName = address.StreetName,
|
StreetName = address.StreetName,
|
||||||
HouseNumber = address.HouseNumber,
|
HouseNumber = address.HouseNumber,
|
||||||
ZipCode = address.ZipCode
|
ZipCode = address.ZipCode
|
||||||
});
|
});
|
||||||
if (!VInfos.Any())
|
if (!_vInfos.Any())
|
||||||
{
|
{
|
||||||
ToastService.ShowError($"Ingen virksomheder fundet.");
|
ToastService.ShowError($"Ingen virksomheder fundet.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void SelectCompany(string vatNumber)
|
private void SelectCompany(string vatNumber, bool syncAll)
|
||||||
{
|
{
|
||||||
_virkRegInfo = (from x in VInfos where x.VatNumber == vatNumber select x).First();
|
_virkRegInfo = (from x in _vInfos where x.VatNumber == vatNumber select x).First();
|
||||||
CompanyDto.Name = _virkRegInfo.Name;
|
if (syncAll)
|
||||||
CompanyDto.Address1 = _virkRegInfo.CoName;
|
{
|
||||||
CompanyDto.Address2 = _virkRegInfo.Address;
|
_companyView.VatNumber = _virkRegInfo.VatNumber;
|
||||||
CompanyDto.ZipCode = _virkRegInfo.ZipCode;
|
_companyView.Name = _virkRegInfo.Name;
|
||||||
CompanyDto.City = _virkRegInfo.City;
|
_companyView.Address1 = _virkRegInfo.CoName;
|
||||||
CompanyDto.VatNumber = _virkRegInfo.VatNumber;
|
_companyView.Address2 = _virkRegInfo.Address;
|
||||||
|
_companyView.ZipCode = _virkRegInfo.ZipCode;
|
||||||
|
_companyView.City = _virkRegInfo.City;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_companyView.VatNumber = _virkRegInfo.VatNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
_vInfos = new List<VirkRegInfo>();
|
||||||
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Interceptor.DisposeEvent();
|
Interceptor.DisposeEvent();
|
||||||
|
_updateCompany.OnFieldChanged -= HandleFieldChanged;
|
||||||
|
_updateCompany.OnValidationStateChanged -= ValidationChanged;
|
||||||
|
}
|
||||||
|
private static VatAddress PrepareVatAddress(CompanyDto model)
|
||||||
|
{
|
||||||
|
var digits = "123456789".ToCharArray();
|
||||||
|
var pos1 = model.Address1.IndexOfAny(digits);
|
||||||
|
if (pos1 > 0)
|
||||||
|
{
|
||||||
|
return new VatAddress
|
||||||
|
{
|
||||||
|
ZipCode = model.ZipCode,
|
||||||
|
StreetName = model.Address1[..pos1],
|
||||||
|
HouseNumber = Regex.Replace(model.Address1[pos1..], "[^0-9]", "")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var pos2 = model.Address2.IndexOfAny(digits);
|
||||||
|
if (pos2 > 0)
|
||||||
|
{
|
||||||
|
return new VatAddress
|
||||||
|
{
|
||||||
|
ZipCode = model.ZipCode,
|
||||||
|
StreetName = model.Address2[..pos2],
|
||||||
|
HouseNumber = Regex.Replace(model.Address2[pos2..], "[^0-9]", "")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return new VatAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,56 +21,67 @@
|
||||||
@using Wonky.Client.Helpers
|
@using Wonky.Client.Helpers
|
||||||
@attribute [Authorize(Roles = "Adviser")]
|
@attribute [Authorize(Roles = "Adviser")]
|
||||||
|
|
||||||
@if (CompanyDto != null)
|
@if (_companyDto != null)
|
||||||
{
|
{
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="h2"><img src="gravestone.png" class="img-fluid" style="float:left;width:48px;height:48px;display:@(_hasFolded ? "block" : "none")" alt="tombstone"/> @CompanyDto.Name</div>
|
<div class="h2">
|
||||||
|
<img src="gravestone.png" class="img-fluid"
|
||||||
|
style="float:left;width:48px;height:48px;display:@(_companyDto.HasFolded == 1 ? "block" : "none")" alt="tombstone"/>
|
||||||
|
@_companyDto.Name
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<table class="table table-sm table-striped table-bordered">
|
<table class="table table-sm table-striped table-bordered">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Konto</th>
|
<th scope="row">Konto</th>
|
||||||
<td colspan="2">@CompanyDto.Account</td>
|
<td colspan="2">@_companyDto.Account</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Conavn</th>
|
<th scope="row">Conavn</th>
|
||||||
<td colspan="2">@CompanyDto.Address1</td>
|
<td colspan="2">@_companyDto.Address1</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Adresse</th>
|
<th scope="row">Adresse</th>
|
||||||
<td colspan="2">@CompanyDto.Address2</td>
|
<td colspan="2">@_companyDto.Address2</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Postnummer</th>
|
<th scope="row">Postnummer</th>
|
||||||
<td colspan="2">@CompanyDto.ZipCode</td>
|
<td colspan="2">@_companyDto.ZipCode</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Bynavn</th>
|
<th scope="row">Bynavn</th>
|
||||||
<td colspan="2">@CompanyDto.City</td>
|
<td colspan="2">@_companyDto.City</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">CVR</th>
|
<th scope="row">CVR</th>
|
||||||
<td class="state"><DisplayStateComponent StateClass="@_vatState"></DisplayStateComponent></td>
|
<td class="state">
|
||||||
<td>@CompanyDto.VatNumber</td>
|
<DisplayStateComponent StateClass="@_vatState"></DisplayStateComponent>
|
||||||
|
</td>
|
||||||
|
<td>@_companyDto.VatNumber</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Telefon</th>
|
<th scope="row">Telefon</th>
|
||||||
<td colspan="2">@CompanyDto.Phone</td>
|
<td colspan="2">@_companyDto.Phone</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Email</th>
|
<th scope="row">Email</th>
|
||||||
<td colspan="2">@CompanyDto.Email</td>
|
<td colspan="2">@_companyDto.Email</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Sidste besøg</th>
|
<th scope="row">Sidste besøg</th>
|
||||||
<td colspan="2">@CompanyDto.LastVisit</td>
|
<td colspan="2">@_companyDto.LastVisit</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Næste besøg</th>
|
<th scope="row">Næste besøg</th>
|
||||||
<td class="state"><DisplayStateComponent StateClass="@(_hasFolded ? "the-dead" : Utils.GetVisitState(CompanyDto.NextVisit))"></DisplayStateComponent></td>
|
<td class="state">
|
||||||
<td>@CompanyDto.NextVisit</td>
|
<DisplayStateComponent
|
||||||
|
StateClass="@(_companyDto.HasFolded == 1
|
||||||
|
? "the-dead" : Utils.GetVisitState(_companyDto.NextVisit))">
|
||||||
|
</DisplayStateComponent>
|
||||||
|
</td>
|
||||||
|
<td>@_companyDto.NextVisit</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -78,14 +89,16 @@
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<div class="d-flex align-items-end">
|
<div class="d-flex align-items-end">
|
||||||
<a class="btn btn-primary mx-2" href="/companies">Tilbage</a>
|
<a class="btn btn-primary mx-2" href="/companies">Tilbage</a>
|
||||||
<a class="btn btn-primary mx-2" href="/company/@(CompanyDto.CompanyId)/update">Rediger</a>
|
<a class="btn btn-primary mx-2" href="/company/@(_companyDto.CompanyId)/update">Rediger</a>
|
||||||
@if (_vatInvalid || string.IsNullOrWhiteSpace(CompanyDto.Address1))
|
@if (_vatInvalid || string.IsNullOrWhiteSpace(_companyDto.Address1))
|
||||||
{
|
{
|
||||||
<a type="button" class="btn btn-primary mx-2 disabled" aria-disabled="true">Aktivitet</a>
|
<a type="button" class="btn btn-primary mx-2 disabled" aria-disabled="true">Kanvas/Nulsalg</a>
|
||||||
|
<a type="button" class="btn btn-primary mx-2 disabled" aria-disabled="true">Besøg</a>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<a type="button" class="btn btn-primary mx-2" href="/company/@CompanyDto.CompanyId/activity">Aktivitet</a>
|
<a type="button" class="btn btn-primary mx-2 disabled" aria-disabled="true">Kanvas/Nulsalg</a>
|
||||||
|
<a type="button" class="btn btn-primary mx-2" href="/company/@_companyDto.CompanyId/activity">Aktivittet</a>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Blazored.LocalStorage;
|
||||||
using Blazored.Toast.Services;
|
using Blazored.Toast.Services;
|
||||||
using Wonky.Client.HttpInterceptors;
|
using Wonky.Client.HttpInterceptors;
|
||||||
using Wonky.Client.HttpRepository;
|
using Wonky.Client.HttpRepository;
|
||||||
|
@ -23,6 +24,7 @@ using Wonky.Client.Helpers;
|
||||||
using Wonky.Client.Services;
|
using Wonky.Client.Services;
|
||||||
using Wonky.Entity.DTO;
|
using Wonky.Entity.DTO;
|
||||||
using Wonky.Entity.Models;
|
using Wonky.Entity.Models;
|
||||||
|
using Wonky.Entity.Views;
|
||||||
|
|
||||||
namespace Wonky.Client.Pages;
|
namespace Wonky.Client.Pages;
|
||||||
|
|
||||||
|
@ -34,28 +36,23 @@ public partial class CompanyView : IDisposable
|
||||||
[Inject] public ICompanyHttpRepository CompanyRepo { get; set; }
|
[Inject] public ICompanyHttpRepository CompanyRepo { get; set; }
|
||||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||||
[Inject] public VatInfoLookupService VatInfoLookup { get; set; }
|
[Inject] public VatInfoLookupService VatInfoLookup { get; set; }
|
||||||
|
[Inject] public ILocalStorageService Storage { get; set; }
|
||||||
[Parameter] public string CompanyId { get; set; } = "";
|
[Parameter] public string CompanyId { get; set; } = "";
|
||||||
private CompanyDto CompanyDto { get; set; } = new ();
|
private CompanyDto _companyDto = new ();
|
||||||
private string _vatState { get; set; } = "the-dead";
|
private string _vatState = "the-dead";
|
||||||
private bool _hasFolded;
|
private bool _vatInvalid = true;
|
||||||
private bool _vatInvalid;
|
|
||||||
private VatUtils _vatUtils { get; set; }
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
_vatUtils = new VatUtils();
|
|
||||||
Interceptor.RegisterEvent();
|
Interceptor.RegisterEvent();
|
||||||
Interceptor.RegisterBeforeSendEvent();
|
Interceptor.RegisterBeforeSendEvent();
|
||||||
CompanyDto = await CompanyRepo.GetCompanyById(CompanyId);
|
var xu = await Storage.GetItemAsync<UserInfoView>("_xu");
|
||||||
|
_companyDto = await CompanyRepo.GetCompanyById(CompanyId);
|
||||||
if(CompanyDto.HasFolded == 1)
|
_companyDto.CountryCode = xu.CountryCode;
|
||||||
|
if (_companyDto.HasFolded == 0)
|
||||||
{
|
{
|
||||||
_hasFolded = true;
|
_vatInvalid = !VatUtils.ValidateFormat(_companyDto.CountryCode, _companyDto.VatNumber);
|
||||||
}
|
_vatState = _vatInvalid ? "the-draw" : "the-good";
|
||||||
else
|
|
||||||
{
|
|
||||||
_vatInvalid = !_vatUtils.ValidateFormat(CompanyDto.CountryCode, CompanyDto.VatNumber);
|
|
||||||
_vatState = _vatUtils.ValidateFormat(CompanyDto.CountryCode, CompanyDto.VatNumber) ? "the-good" : "the-draw";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
<label for="activityType" class="col-md-2 col-form-label">Kontakt</label>
|
<label for="activityType" class="col-md-2 col-form-label">Kontakt</label>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<select id="activityType" class="form-select" @bind-Value="@_poDraft.ActivityTypeEnum" @bind-Value:event="oninput" @onchange="CheckActivity">
|
<select id="activityType" class="form-select" @bind-Value="@_poDraft.ActivityTypeEnum" @bind-Value:event="oninput" @onchange="CheckActivity">
|
||||||
<option value="" selected>"IKKE VALGT"</option>
|
<option value="" selected disabled>"IKKE VALGT"</option>
|
||||||
<option value="onSite">Besøg</option>
|
<option value="onSite">Besøg</option>
|
||||||
<option value="phone">Telefon</option>
|
<option value="phone">Telefon</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
<label for="statusType" class="col-md-2 col-form-label">Status</label>
|
<label for="statusType" class="col-md-2 col-form-label">Status</label>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<select id="statusType" class="form-select" @bind-Value="@_poDraft.ActivityStatusEnum" @bind-Value:event="oninput" @onchange="CheckStatus">
|
<select id="statusType" class="form-select" @bind-Value="@_poDraft.ActivityStatusEnum" @bind-Value:event="oninput" @onchange="CheckStatus">
|
||||||
<option value="" selected>"IKKE VALGT"</option>
|
<option value="" selected disabled>"IKKE VALGT"</option>
|
||||||
<option value="noSale">Ingen salg</option>
|
<option value="noSale">Ingen salg</option>
|
||||||
<option value="order">Bestilling</option>
|
<option value="order">Bestilling</option>
|
||||||
<option value="quote">Tilbud</option>
|
<option value="quote">Tilbud</option>
|
||||||
|
@ -247,7 +247,7 @@
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-end">
|
<li class="list-group-item d-flex justify-content-between align-items-end">
|
||||||
<div class="text-sm-start px-2">@rate.Quantity</div>
|
<div class="text-sm-start px-2">@rate.Quantity</div>
|
||||||
<div class="text-sm-end">@rate.Rate</div>
|
<div class="text-sm-end">@rate.Rate</div>
|
||||||
<button class="btn btn-primary btn-sm" @onclick="@(() => SelectItem(item.ItemId, rate.Quantity, rate.Rate))">Vælg</button>
|
<button type="button" class="btn btn-primary btn-sm" @onclick="@(() => SelectItem(item.ItemId, rate.Quantity, rate.Rate))">Vælg</button>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -309,7 +309,7 @@
|
||||||
<input type="checkbox" class="form-check" @bind-value="@Sas"/>
|
<input type="checkbox" class="form-check" @bind-value="@Sas"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<button class="btn btn-info" @onclick="@(() => AddItem(_selectedItem))">Læg til</button>
|
<button type="button" class="btn btn-info" @onclick="@(() => AddItem(_selectedItem))">Læg til</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -347,7 +347,7 @@
|
||||||
<input type="checkbox" checked="@cItem.Sas" disabled/>
|
<input type="checkbox" checked="@cItem.Sas" disabled/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-warning" @onclick="@(() => RemoveItem(@cItem))">Slet</button>
|
<button type="button" class="btn btn-warning" @onclick="@(() => RemoveItem(@cItem))">Slet</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
|
@ -366,7 +366,7 @@
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<button class="btn btn-danger" @onclick="@DeleteDraft" disabled="@(DraftStateProvider.Draft.Items.Count == 0)">Slet kladde</button>
|
<button type="button" class="btn btn-danger" @onclick="@DeleteDraft" disabled="@(DraftStateProvider.Draft.Items.Count == 0)">Slet kladde</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -375,10 +375,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-2 mb-2">
|
<div class="row mt-2 mb-2">
|
||||||
<div class="col">
|
<div class="col-md-6"></div>
|
||||||
|
<div class="col-md-2">
|
||||||
<a class="btn btn-primary" href="/company/@NgCompany.CompanyId">Tilbage</a>
|
<a class="btn btn-primary" href="/company/@NgCompany.CompanyId">Tilbage</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col-md-2">
|
||||||
@* <button type="submit" class="btn btn-success" disabled="@InvalidActivity">Gem</button> *@
|
@* <button type="submit" class="btn btn-success" disabled="@InvalidActivity">Gem</button> *@
|
||||||
<button type="submit" class="btn btn-success">OK</button>
|
<button type="submit" class="btn btn-success">OK</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -63,7 +63,6 @@ public partial class CrmActivityCreate : IDisposable
|
||||||
private bool InvalidCanvas { get; set; } = true;
|
private bool InvalidCanvas { get; set; } = true;
|
||||||
private bool InvalidDate { get; set; } = true;
|
private bool InvalidDate { get; set; } = true;
|
||||||
private UserInfoView Ux { get; set; } = new();
|
private UserInfoView Ux { get; set; } = new();
|
||||||
private VatUtils _vatUtils { get; set; }
|
|
||||||
private DateTime _draftDate { get; set; }
|
private DateTime _draftDate { get; set; }
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
|
@ -76,7 +75,6 @@ public partial class CrmActivityCreate : IDisposable
|
||||||
Interceptor.RegisterEvent();
|
Interceptor.RegisterEvent();
|
||||||
Interceptor.RegisterBeforeSendEvent();
|
Interceptor.RegisterBeforeSendEvent();
|
||||||
|
|
||||||
_vatUtils = new VatUtils();
|
|
||||||
_prefs = await UserPrefs.GetPreferences();
|
_prefs = await UserPrefs.GetPreferences();
|
||||||
_paging.SearchColumn = _prefs.ItemSearch;
|
_paging.SearchColumn = _prefs.ItemSearch;
|
||||||
_paging.PageSize = Convert.ToInt32(_prefs.PageSize);
|
_paging.PageSize = Convert.ToInt32(_prefs.PageSize);
|
||||||
|
@ -84,10 +82,6 @@ public partial class CrmActivityCreate : IDisposable
|
||||||
Ux = await StorageService.GetItemAsync<UserInfoView>("_xu");
|
Ux = await StorageService.GetItemAsync<UserInfoView>("_xu");
|
||||||
NgCompany = await CompanyRepo.GetCompanyById(CompanyId);
|
NgCompany = await CompanyRepo.GetCompanyById(CompanyId);
|
||||||
|
|
||||||
DraftContext = new EditContext(_poDraft);
|
|
||||||
DraftContext.OnFieldChanged += HandleFieldChanged;
|
|
||||||
DraftContext.OnValidationStateChanged += ValidationChanged;
|
|
||||||
|
|
||||||
// set up identification
|
// set up identification
|
||||||
_poDraft.SalesHeadId = "";
|
_poDraft.SalesHeadId = "";
|
||||||
_poDraft.CompanyId = CompanyId;
|
_poDraft.CompanyId = CompanyId;
|
||||||
|
@ -114,6 +108,11 @@ public partial class CrmActivityCreate : IDisposable
|
||||||
_poDraft.DlvAddress2 = NgCompany.Address2;
|
_poDraft.DlvAddress2 = NgCompany.Address2;
|
||||||
_poDraft.DlvZipCode = NgCompany.ZipCode;
|
_poDraft.DlvZipCode = NgCompany.ZipCode;
|
||||||
_poDraft.DlvCity = NgCompany.City;
|
_poDraft.DlvCity = NgCompany.City;
|
||||||
|
|
||||||
|
DraftContext = new EditContext(_poDraft);
|
||||||
|
DraftContext.OnFieldChanged += HandleFieldChanged;
|
||||||
|
DraftContext.OnValidationStateChanged += ValidationChanged;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CreateActivity()
|
private async Task CreateActivity()
|
||||||
|
@ -152,7 +151,7 @@ public partial class CrmActivityCreate : IDisposable
|
||||||
|
|
||||||
await StorageService.SetItemAsync(CompanyId, _poDraft);
|
await StorageService.SetItemAsync(CompanyId, _poDraft);
|
||||||
|
|
||||||
var result = await ActivityRepo.CreateActivity(_poDraft).ConfigureAwait(true);
|
var result = await ActivityRepo.CreateActivity(_poDraft);
|
||||||
Console.WriteLine(JsonSerializer.Serialize(result));
|
Console.WriteLine(JsonSerializer.Serialize(result));
|
||||||
ToastService.ShowSuccess($"{result.Message}.");
|
ToastService.ShowSuccess($"{result.Message}.");
|
||||||
NavigationManager.NavigateTo($"/companies");
|
NavigationManager.NavigateTo($"/companies");
|
||||||
|
@ -270,20 +269,26 @@ public partial class CrmActivityCreate : IDisposable
|
||||||
|
|
||||||
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
||||||
{
|
{
|
||||||
_poFormInvalid = !DraftContext.Validate();
|
|
||||||
InvalidCanvas = InvalidActivityType || InvalidDate;
|
InvalidCanvas = InvalidActivityType || InvalidDate;
|
||||||
InvalidActivity = InvalidActivityType
|
InvalidActivity = InvalidActivityType
|
||||||
|| _poFormInvalid
|
|| _poFormInvalid
|
||||||
|| DraftStateProvider.Draft.Items.Count == 0
|
|| DraftStateProvider.Draft.Items.Count == 0
|
||||||
|| InvalidDate
|
|| InvalidDate
|
||||||
|| (_poDraft.ActivityStatusEnum == "offer" && string.IsNullOrWhiteSpace(_poDraft.EMail));
|
|| (_poDraft.ActivityStatusEnum == "offer" && string.IsNullOrWhiteSpace(_poDraft.EMail));
|
||||||
|
|
||||||
|
if (InvalidCanvas || InvalidActivity)
|
||||||
|
{
|
||||||
|
_poFormInvalid = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_poFormInvalid = !DraftContext.Validate();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_poDraft.VatNumber))
|
if (!string.IsNullOrEmpty(_poDraft.VatNumber))
|
||||||
{
|
{
|
||||||
if(!_vatUtils.ValidateFormat(NgCompany.CountryCode, _poDraft.VatNumber))
|
if(!VatUtils.ValidateFormat(NgCompany.CountryCode, _poDraft.VatNumber))
|
||||||
ToastService.ShowWarning("CVR / ORG nummer er ikke et gyldigt registreringsnummer");
|
ToastService.ShowWarning("CVR / ORG nummer er ikke et gyldigt registreringsnummer");
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(_poDraft.ActivityTypeEnum))
|
if (string.IsNullOrEmpty(_poDraft.ActivityTypeEnum))
|
||||||
|
|
|
@ -13,13 +13,17 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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]
|
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||||
//
|
//
|
||||||
*@@using Wonky.Client.Components
|
*@
|
||||||
|
|
||||||
|
@using Wonky.Client.Components
|
||||||
|
@using Microsoft.Extensions.Options
|
||||||
|
@using Wonky.Entity.Configuration
|
||||||
@page "/info"
|
@page "/info"
|
||||||
<AuthorizeView>
|
<AuthorizeView>
|
||||||
<Authorized>
|
<Authorized>
|
||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<div class="col text-center">
|
<div class="col text-center">
|
||||||
<img class="grumpy-coder" src="grumpy-coder.png" alt="Wonky Logo"/>
|
<img class="grumpy-coder" src="@_app?.Image" alt="Wonky Logo"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -37,4 +41,15 @@
|
||||||
</div>
|
</div>
|
||||||
</Authorized>
|
</Authorized>
|
||||||
</AuthorizeView>
|
</AuthorizeView>
|
||||||
|
@code{
|
||||||
|
|
||||||
|
[Inject] IOptions<AppInfo>? AppInfo { get; set; }
|
||||||
|
private AppInfo? _app;
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
_app = AppInfo?.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
<div class="card mb-3">
|
<div class="card mb-3">
|
||||||
<div class="row g-0 d-flex align-items-center">
|
<div class="row g-0 d-flex align-items-center">
|
||||||
<div class="col-lg-4 d-none d-lg-flex">
|
<div class="col-lg-4 d-none d-lg-flex">
|
||||||
<img src="grumpy-coder.png" alt="Innotec Danmark"
|
<img src="grumpy-coder.png" alt="Innotec Danmark" style="max-height: 300px; max-width: 300px"
|
||||||
class="w-100 rounded-t-5 rounded-tr-lg-0 rounded-bl-lg-5"/>
|
class="img-fluid w-100 rounded-t-5 rounded-tr-lg-0 rounded-bl-lg-5"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-8">
|
<div class="col-lg-8">
|
||||||
<div class="card-body py-5 px-md-5">
|
<div class="card-body py-5 px-md-5">
|
||||||
|
|
|
@ -28,7 +28,7 @@ public partial class Logout
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
await AuthenticationService.Logout().ConfigureAwait(true);
|
await AuthenticationService.Logout();
|
||||||
|
|
||||||
NavigationManager.NavigateTo("/");
|
NavigationManager.NavigateTo("/");
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,9 @@
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<th scope="col">Dagtype</th>
|
<th scope="col">Dag Type</th>
|
||||||
<th scope="col">Begyndt</th>
|
<th scope="col">Dag Begyndt</th>
|
||||||
<th scope="col">Afsluttet</th>
|
<th scope="col">Dag Afsluttet</th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -48,7 +48,7 @@ public partial class SalesReport
|
||||||
? DateTime.Now
|
? DateTime.Now
|
||||||
: DateTime.Parse(_prefs.WorkDate);
|
: DateTime.Parse(_prefs.WorkDate);
|
||||||
_reportDto.CheckOut = _reportDto.CheckIn;
|
_reportDto.CheckOut = _reportDto.CheckIn;
|
||||||
await UserPrefs.SetWorkDate(_reportDto.CheckIn).ConfigureAwait(true);
|
await UserPrefs.SetWorkDate(_reportDto.CheckIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
||||||
|
@ -73,10 +73,10 @@ public partial class SalesReport
|
||||||
private async Task GetActivities()
|
private async Task GetActivities()
|
||||||
{
|
{
|
||||||
Activities = null;
|
Activities = null;
|
||||||
await UserPrefs.SetWorkDate(_reportDto.CheckIn).ConfigureAwait(true);
|
await UserPrefs.SetWorkDate(_reportDto.CheckIn);
|
||||||
Activities = await ActivityRepo
|
Activities = await ActivityRepo
|
||||||
.GetActivities($"{_reportDto.CheckIn:yyyy-MM-dd}")
|
.GetActivities($"{_reportDto.CheckIn:yyyy-MM-dd}")
|
||||||
.ConfigureAwait(true);
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
@ -46,6 +46,7 @@ builder.Services.AddBlazoredToast();
|
||||||
builder.Services.AddHttpClientInterceptor();
|
builder.Services.AddHttpClientInterceptor();
|
||||||
|
|
||||||
builder.Services.Configure<ApiConfig>(builder.Configuration.GetSection("ApiConfig"));
|
builder.Services.Configure<ApiConfig>(builder.Configuration.GetSection("ApiConfig"));
|
||||||
|
builder.Services.Configure<AppInfo>(builder.Configuration.GetSection("AppInfo"));
|
||||||
|
|
||||||
builder.Services.AddScoped<ICompanyHttpRepository, CompanyHttpRepository>();
|
builder.Services.AddScoped<ICompanyHttpRepository, CompanyHttpRepository>();
|
||||||
builder.Services.AddScoped<ISalesItemHttpRepository, SalesItemHttpRepository>();
|
builder.Services.AddScoped<ISalesItemHttpRepository, SalesItemHttpRepository>();
|
||||||
|
|
|
@ -54,11 +54,9 @@ namespace Wonky.Client.Services
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await _client
|
var response = await _client
|
||||||
.PostAsync(_apiConfig.Value.TokenPath, new FormUrlEncodedContent(credentials))
|
.PostAsync(_apiConfig.Value.TokenPath, new FormUrlEncodedContent(credentials));
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
var resContent = await response.Content.ReadAsStringAsync()
|
var resContent = await response.Content.ReadAsStringAsync();
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
// if not success - return error status
|
// if not success - return error status
|
||||||
if (!response.IsSuccessStatusCode)
|
if (!response.IsSuccessStatusCode)
|
||||||
|
@ -69,93 +67,56 @@ namespace Wonky.Client.Services
|
||||||
|
|
||||||
// process response content
|
// process response content
|
||||||
var data = JsonSerializer.Deserialize<AuthResponseView>(resContent, _options);
|
var data = JsonSerializer.Deserialize<AuthResponseView>(resContent, _options);
|
||||||
|
await _localStorage.SetItemAsync("_xa", data.AccessToken);
|
||||||
await _localStorage.SetItemAsync("_xa", data.AccessToken)
|
await _localStorage.SetItemAsync("_xr", data.RefreshToken);
|
||||||
.ConfigureAwait(true);
|
await _localStorage.SetItemAsync("_xe", (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds + data.ExpiresIn - 60);
|
||||||
|
|
||||||
await _localStorage.SetItemAsync("_xr", data.RefreshToken)
|
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
await _localStorage.SetItemAsync("_xe",
|
|
||||||
(int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds + data.ExpiresIn - 60)
|
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
// set default request headers using access_token
|
// set default request headers using access_token
|
||||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", data.AccessToken);
|
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", data.AccessToken);
|
||||||
|
|
||||||
var userInfo = await UserInfo();
|
var userInfo = await UserInfo();
|
||||||
|
await _localStorage.SetItemAsync("_xu", userInfo);
|
||||||
await _localStorage.SetItemAsync("_xu", userInfo)
|
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
// notify system on state change
|
// notify system on state change
|
||||||
((AuthStateProvider)_authStateProvider).NotifyUserAuthenticationAsync(data.AccessToken);
|
((AuthStateProvider)_authStateProvider).NotifyUserAuthenticationAsync(data.AccessToken);
|
||||||
|
|
||||||
data.IsSuccess = true;
|
data.IsSuccess = true;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> RefreshToken()
|
public async Task<string> RefreshToken()
|
||||||
{
|
{
|
||||||
var refreshToken = await _localStorage.GetItemAsync<string>("_xr")
|
var refreshToken = await _localStorage.GetItemAsync<string>("_xr");
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
var credentials = new Dictionary<string, string>
|
var credentials = new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
["grant_type"] = "refresh_token",
|
["grant_type"] = "refresh_token",
|
||||||
["refresh_token"] = refreshToken
|
["refresh_token"] = refreshToken
|
||||||
};
|
};
|
||||||
|
var response = await _client.PostAsync(_apiConfig.Value.TokenPath, new FormUrlEncodedContent(credentials));
|
||||||
var response = await _client.PostAsync(_apiConfig.Value.TokenPath, new FormUrlEncodedContent(credentials))
|
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode) return string.Empty;
|
if (!response.IsSuccessStatusCode) return string.Empty;
|
||||||
var resContent = await response.Content.ReadAsStringAsync()
|
var resContent = await response.Content.ReadAsStringAsync();
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
var data = JsonSerializer.Deserialize<AuthResponseView>(resContent, _options);
|
var data = JsonSerializer.Deserialize<AuthResponseView>(resContent, _options);
|
||||||
|
|
||||||
// set default request headers using access_token
|
// set default request headers using access_token
|
||||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", data.AccessToken);
|
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", data.AccessToken);
|
||||||
|
await _localStorage.SetItemAsync("_xa", data.AccessToken);
|
||||||
await _localStorage.SetItemAsync("_xa", data.AccessToken)
|
await _localStorage.SetItemAsync("_xr", data.RefreshToken);
|
||||||
.ConfigureAwait(true);
|
await _localStorage.SetItemAsync("_xe", (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds + data.ExpiresIn - 60);
|
||||||
|
|
||||||
await _localStorage.SetItemAsync("_xr", data.RefreshToken)
|
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
await _localStorage.SetItemAsync("_xe",
|
|
||||||
(int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds + data.ExpiresIn - 60)
|
|
||||||
.ConfigureAwait(true);
|
|
||||||
return data.AccessToken;
|
return data.AccessToken;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Logout()
|
public async Task Logout()
|
||||||
{
|
{
|
||||||
await _localStorage.ClearAsync()
|
await _localStorage.ClearAsync();
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
((AuthStateProvider)_authStateProvider).NotifyUserLogout();
|
((AuthStateProvider)_authStateProvider).NotifyUserLogout();
|
||||||
|
|
||||||
_client.DefaultRequestHeaders.Authorization = null;
|
_client.DefaultRequestHeaders.Authorization = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<UserInfoView> UserInfo(bool write = false)
|
public async Task<UserInfoView> UserInfo(bool write = false)
|
||||||
{
|
{
|
||||||
var infoResponse = await _client.GetAsync(_apiConfig.Value.UserInfo)
|
var infoResponse = await _client.GetAsync(_apiConfig.Value.UserInfo);
|
||||||
.ConfigureAwait(true);
|
var infoContent = await infoResponse.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
var infoContent = await infoResponse.Content.ReadAsStringAsync()
|
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
var userInfo = JsonSerializer.Deserialize<UserInfoView>(infoContent, _options);
|
var userInfo = JsonSerializer.Deserialize<UserInfoView>(infoContent, _options);
|
||||||
if(write)
|
if(write)
|
||||||
await _localStorage.SetItemAsync("_xu", userInfo).ConfigureAwait(true);
|
await _localStorage.SetItemAsync("_xu", userInfo);
|
||||||
|
|
||||||
return userInfo ?? new UserInfoView();
|
return userInfo ?? new UserInfoView();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,7 @@ public class RefreshTokenService
|
||||||
|
|
||||||
public async Task<string> TryRefreshToken()
|
public async Task<string> TryRefreshToken()
|
||||||
{
|
{
|
||||||
var authState = await _authStateProvider.GetAuthenticationStateAsync()
|
var authState = await _authStateProvider.GetAuthenticationStateAsync();
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
var user = authState.User;
|
var user = authState.User;
|
||||||
|
|
||||||
|
@ -47,7 +46,7 @@ public class RefreshTokenService
|
||||||
|
|
||||||
var diff = expTime - DateTime.UtcNow;
|
var diff = expTime - DateTime.UtcNow;
|
||||||
return diff.TotalMinutes <= 2
|
return diff.TotalMinutes <= 2
|
||||||
? await _authService.RefreshToken()
|
? await _authService.RefreshToken().ConfigureAwait(true)
|
||||||
: string.Empty;
|
: string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,7 @@ public class UserPreferenceService
|
||||||
WorkDate = $"{workDate:yyyy-MM-dd}"
|
WorkDate = $"{workDate:yyyy-MM-dd}"
|
||||||
};
|
};
|
||||||
|
|
||||||
await _localStorageService.SetItemAsync("preferences", newPreferences)
|
await _localStorageService.SetItemAsync("preferences", newPreferences);
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
OnChange?.Invoke(newPreferences);
|
OnChange?.Invoke(newPreferences);
|
||||||
}
|
}
|
||||||
|
@ -40,63 +39,54 @@ public class UserPreferenceService
|
||||||
var newPreferences = preferences
|
var newPreferences = preferences
|
||||||
with { CompanySearch = companySearch };
|
with { CompanySearch = companySearch };
|
||||||
|
|
||||||
await _localStorageService.SetItemAsync("preferences", newPreferences)
|
await _localStorageService.SetItemAsync("preferences", newPreferences);
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
OnChange?.Invoke(newPreferences);
|
OnChange?.Invoke(newPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SetCompanySort(string companySort)
|
public async Task SetCompanySort(string companySort)
|
||||||
{
|
{
|
||||||
var preferences = await GetPreferences()
|
var preferences = await GetPreferences();
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
var newPreferences = preferences
|
var newPreferences = preferences
|
||||||
with { CompanySort = companySort };
|
with { CompanySort = companySort };
|
||||||
|
|
||||||
await _localStorageService.SetItemAsync("preferences", newPreferences)
|
await _localStorageService.SetItemAsync("preferences", newPreferences);
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
OnChange?.Invoke(newPreferences);
|
OnChange?.Invoke(newPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SetItemSearch(string itemSearch)
|
public async Task SetItemSearch(string itemSearch)
|
||||||
{
|
{
|
||||||
var preferences = await GetPreferences()
|
var preferences = await GetPreferences();
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
var newPreferences = preferences
|
var newPreferences = preferences
|
||||||
with { ItemSearch = itemSearch };
|
with { ItemSearch = itemSearch };
|
||||||
|
|
||||||
await _localStorageService.SetItemAsync("preferences", newPreferences)
|
await _localStorageService.SetItemAsync("preferences", newPreferences);
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
OnChange?.Invoke(newPreferences);
|
OnChange?.Invoke(newPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SetItemSort(string itemSort)
|
public async Task SetItemSort(string itemSort)
|
||||||
{
|
{
|
||||||
var preferences = await GetPreferences()
|
var preferences = await GetPreferences();
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
var newPreferences = preferences
|
var newPreferences = preferences
|
||||||
with { ItemSort = itemSort };
|
with { ItemSort = itemSort };
|
||||||
|
|
||||||
await _localStorageService.SetItemAsync("preferences", newPreferences)
|
await _localStorageService.SetItemAsync("preferences", newPreferences);
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
OnChange?.Invoke(newPreferences);
|
OnChange?.Invoke(newPreferences);
|
||||||
}
|
}
|
||||||
public async Task SetPageSize(string pageSize)
|
public async Task SetPageSize(string pageSize)
|
||||||
{
|
{
|
||||||
var preferences = await GetPreferences()
|
var preferences = await GetPreferences();
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
var newPreferences = preferences
|
var newPreferences = preferences
|
||||||
with { PageSize = pageSize };
|
with { PageSize = pageSize };
|
||||||
|
|
||||||
await _localStorageService.SetItemAsync("preferences", newPreferences)
|
await _localStorageService.SetItemAsync("preferences", newPreferences);
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
OnChange?.Invoke(newPreferences);
|
OnChange?.Invoke(newPreferences);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,13 @@ public class VatInfoLookupService
|
||||||
private readonly HttpClient _client;
|
private readonly HttpClient _client;
|
||||||
private readonly IOptions<ApiConfig> _apiConfig;
|
private readonly IOptions<ApiConfig> _apiConfig;
|
||||||
private readonly List<VirkRegInfo> _noData = new() { new VirkRegInfo { Name = "INGEN DATA" } };
|
private readonly List<VirkRegInfo> _noData = new() { new VirkRegInfo { Name = "INGEN DATA" } };
|
||||||
|
private readonly ApiConfig _config;
|
||||||
|
|
||||||
public VatInfoLookupService(HttpClient client, IOptions<ApiConfig> apiConfig)
|
public VatInfoLookupService(HttpClient client, IOptions<ApiConfig> apiConfig)
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
_apiConfig = apiConfig;
|
_apiConfig = apiConfig;
|
||||||
|
_config = _apiConfig.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<VirkRegInfo>> QueryVirkRegistry(VirkParams query)
|
public async Task<List<VirkRegInfo>> QueryVirkRegistry(VirkParams query)
|
||||||
|
@ -49,18 +51,53 @@ public class VatInfoLookupService
|
||||||
["houseNumber"] = $"{query.HouseNumber}",
|
["houseNumber"] = $"{query.HouseNumber}",
|
||||||
["zipCode"] = $"{query.ZipCode}"
|
["zipCode"] = $"{query.ZipCode}"
|
||||||
};
|
};
|
||||||
var endpoint = QueryHelpers.AddQueryString(_apiConfig.Value.CvrLookup, queryString);
|
var endpoint = QueryHelpers.AddQueryString(_config.BrRegEndpoint, queryString);
|
||||||
var response = await _client.GetAsync(endpoint)
|
var response = await _client.GetAsync(endpoint);
|
||||||
.ConfigureAwait(true);
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
|
var jsonResult = JsonSerializer.Deserialize<List<VirkRegInfo>>(content, _options);
|
||||||
|
if (string.IsNullOrWhiteSpace(content) || !jsonResult.Any()) return _noData;
|
||||||
|
if (!string.IsNullOrWhiteSpace(query.VatNumber)) return jsonResult;
|
||||||
|
var result = jsonResult
|
||||||
|
//.Where(x => x.States[^1].State == "NORMAL")
|
||||||
|
.OrderBy(x => x.Name).ToList();
|
||||||
|
|
||||||
var content = await response.Content.ReadAsStringAsync()
|
return result.Count == 0 ? _noData : result;
|
||||||
.ConfigureAwait(true);
|
}
|
||||||
|
|
||||||
|
public async Task<List<VirkRegInfo>> QueryNoVatRegistry(string vatNumber)
|
||||||
|
{
|
||||||
|
var queryString = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["vatNumber"] = $"{vatNumber}"
|
||||||
|
};
|
||||||
|
var endpoint = QueryHelpers.AddQueryString(_config.BrRegEndpoint, queryString);
|
||||||
|
var response = await _client.GetAsync(endpoint);
|
||||||
|
|
||||||
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
var jsonResult = JsonSerializer.Deserialize<List<VirkRegInfo>>(content, _options);
|
var jsonResult = JsonSerializer.Deserialize<List<VirkRegInfo>>(content, _options);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(content) || !jsonResult.Any()) return _noData;
|
if (string.IsNullOrWhiteSpace(content) || !jsonResult.Any()) return _noData;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(query.VatNumber)) return jsonResult;
|
var result = jsonResult
|
||||||
|
//.Where(x => x.States[^1].State == "NORMAL")
|
||||||
|
.OrderBy(x => x.Name).ToList();
|
||||||
|
|
||||||
|
return result.Count == 0 ? _noData : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<VirkRegInfo>> QueryViesVatRegistry(string vatNumber)
|
||||||
|
{
|
||||||
|
var queryString = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["vatNumber"] = $"{vatNumber}"
|
||||||
|
};
|
||||||
|
var endpoint = QueryHelpers.AddQueryString(_config.ViesEndpoint, queryString);
|
||||||
|
var response = await _client.GetAsync(endpoint);
|
||||||
|
|
||||||
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
|
var jsonResult = JsonSerializer.Deserialize<List<VirkRegInfo>>(content, _options);
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(content) || !jsonResult.Any()) return _noData;
|
||||||
|
|
||||||
var result = jsonResult
|
var result = jsonResult
|
||||||
//.Where(x => x.States[^1].State == "NORMAL")
|
//.Where(x => x.States[^1].State == "NORMAL")
|
||||||
|
@ -74,7 +111,8 @@ public class VatInfoLookupService
|
||||||
if (!string.IsNullOrWhiteSpace(query.VatNumber))
|
if (!string.IsNullOrWhiteSpace(query.VatNumber))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return !string.IsNullOrWhiteSpace(query.HouseNumber) && !string.IsNullOrWhiteSpace(query.StreetName) &&
|
return !string.IsNullOrWhiteSpace(query.HouseNumber)
|
||||||
!string.IsNullOrWhiteSpace(query.ZipCode);
|
&& !string.IsNullOrWhiteSpace(query.StreetName)
|
||||||
|
&& !string.IsNullOrWhiteSpace(query.ZipCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,7 +17,6 @@ using System.Net.Http.Headers;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using Blazored.LocalStorage;
|
using Blazored.LocalStorage;
|
||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
using Wonky.Entity.DTO;
|
|
||||||
using Wonky.Entity.Views;
|
using Wonky.Entity.Views;
|
||||||
|
|
||||||
namespace Wonky.Client.Shared
|
namespace Wonky.Client.Shared
|
||||||
|
@ -38,31 +37,24 @@ namespace Wonky.Client.Shared
|
||||||
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
|
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
|
||||||
{
|
{
|
||||||
// fetch token from localStorage
|
// fetch token from localStorage
|
||||||
var token = await _storage.GetItemAsync<string>("_xa")
|
var token = await _storage.GetItemAsync<string>("_xa");
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(token))
|
if (string.IsNullOrEmpty(token))
|
||||||
// return anonymous if empty
|
// return anonymous if empty
|
||||||
return _anonymous;
|
return _anonymous;
|
||||||
|
|
||||||
// create an authorized user
|
// create an authorized user
|
||||||
var userInfo = await _storage.GetItemAsync<UserInfoView>("_xu")
|
var userInfo = await _storage.GetItemAsync<UserInfoView>("_xu");
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
if (userInfo == null)
|
if (userInfo == null)
|
||||||
return _anonymous;
|
return _anonymous;
|
||||||
|
|
||||||
// set client authorization header
|
// set client authorization header
|
||||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
|
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
|
||||||
|
var exp = await _storage.GetItemAsync<string>("_xe");
|
||||||
var exp = await _storage.GetItemAsync<string>("_xe")
|
|
||||||
.ConfigureAwait(true);
|
|
||||||
|
|
||||||
var roles = ExtractRoles(userInfo);
|
var roles = ExtractRoles(userInfo);
|
||||||
var claims = new List<Claim>
|
var claims = new List<Claim>
|
||||||
{
|
{
|
||||||
new(ClaimTypes.Name, userInfo.FullName),
|
new(ClaimTypes.Name, userInfo.FullName),
|
||||||
new(ClaimTypes.Email, userInfo.Email),
|
new(ClaimTypes.Email, userInfo.Email),
|
||||||
|
new(ClaimTypes.Country, userInfo.CountryCode),
|
||||||
new(ClaimTypes.MobilePhone, userInfo.PhoneNumber),
|
new(ClaimTypes.MobilePhone, userInfo.PhoneNumber),
|
||||||
new(ClaimTypes.Expiration, exp)
|
new(ClaimTypes.Expiration, exp)
|
||||||
};
|
};
|
||||||
|
@ -85,10 +77,10 @@ namespace Wonky.Client.Shared
|
||||||
|
|
||||||
// create an authorized user
|
// create an authorized user
|
||||||
var userInfo = await _storage.GetItemAsync<UserInfoView>("_xu")
|
var userInfo = await _storage.GetItemAsync<UserInfoView>("_xu")
|
||||||
.ConfigureAwait(true);
|
;
|
||||||
|
|
||||||
var exp = await _storage.GetItemAsync<string>("_xe")
|
var exp = await _storage.GetItemAsync<string>("_xe")
|
||||||
.ConfigureAwait(true);
|
;
|
||||||
|
|
||||||
var roles = ExtractRoles(userInfo);
|
var roles = ExtractRoles(userInfo);
|
||||||
var claims = new List<Claim>
|
var claims = new List<Claim>
|
||||||
|
|
|
@ -31,7 +31,7 @@ public partial class DraftStateProvider
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
Draft = await LocalStorageService.GetItemAsync<Draft>(Account)
|
Draft = await LocalStorageService.GetItemAsync<Draft>(Account)
|
||||||
.ConfigureAwait(true);
|
;
|
||||||
|
|
||||||
if (Draft == null || Draft.Items.Count == 0)
|
if (Draft == null || Draft.Items.Count == 0)
|
||||||
{
|
{
|
||||||
|
@ -51,13 +51,13 @@ public partial class DraftStateProvider
|
||||||
public async Task SaveChangesAsync()
|
public async Task SaveChangesAsync()
|
||||||
{
|
{
|
||||||
await LocalStorageService.SetItemAsync(Account, Draft)
|
await LocalStorageService.SetItemAsync(Account, Draft)
|
||||||
.ConfigureAwait(true);
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteDraftAsync()
|
public async Task DeleteDraftAsync()
|
||||||
{
|
{
|
||||||
Draft.Items.Clear();
|
Draft.Items.Clear();
|
||||||
await LocalStorageService.SetItemAsync(Account, Draft)
|
await LocalStorageService.SetItemAsync(Account, Draft)
|
||||||
.ConfigureAwait(true);
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,19 +6,21 @@
|
||||||
"Microsoft": "Information"
|
"Microsoft": "Information"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"app": {
|
"appInfo": {
|
||||||
"name": "Willy Wonka",
|
"name": "Wonky Client",
|
||||||
"version": "0.3",
|
"version": "0.3.y",
|
||||||
"isBeta": true,
|
"isBeta": true,
|
||||||
"image": "grumpy-coder.png"
|
"image": "grumpy-coder.png"
|
||||||
},
|
},
|
||||||
"apiConfig": {
|
"apiConfig": {
|
||||||
"baseAddress": "https://staging.innotec.dk",
|
"baseAddress": "https://dev.innotec.dk",
|
||||||
"tokenPath": "token",
|
"tokenPath": "token",
|
||||||
"userInfo": "api/auth/userinfo",
|
"userInfo": "api/auth/userinfo",
|
||||||
"customerEndpoint": "api/v2/crm/companies",
|
"customerEndpoint": "api/v2/crm/companies",
|
||||||
"catalogEndpoint": "api/v2/crm/catalog",
|
"catalogEndpoint": "api/v2/crm/catalog",
|
||||||
"cvrLookup": "api/v2/services/virk",
|
"dkEndpointVat": "api/v2/services/virk",
|
||||||
|
"noEndpointVat": "api/v2/services/brReg",
|
||||||
|
"seEndpointVat": "api/v2/services/vies",
|
||||||
"glsTrackUrl": "https://www.gls-group.eu/276-I-PORTAL-WEB/content/GLS/DK01/DA/5004.htm?txtAction=71000&txtRefNo=",
|
"glsTrackUrl": "https://www.gls-group.eu/276-I-PORTAL-WEB/content/GLS/DK01/DA/5004.htm?txtAction=71000&txtRefNo=",
|
||||||
"glsId": "",
|
"glsId": "",
|
||||||
"activityEndpoint": "api/v2/crm/salesReps/sales"
|
"activityEndpoint": "api/v2/crm/salesReps/sales"
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
|
|
||||||
/* visit / vat state classes */
|
/* visit / vat state classes */
|
||||||
.state {
|
.state {
|
||||||
width: 8px;
|
width: 24px;
|
||||||
height: 8px;
|
height: 24px;
|
||||||
min-width: 8px;
|
min-width: 24px;
|
||||||
min-height: 8px;
|
min-height: 24px;
|
||||||
}
|
}
|
||||||
.text-inno {
|
.text-inno {
|
||||||
color: #ffaa00;
|
color: #ffaa00;
|
||||||
|
@ -27,16 +27,21 @@
|
||||||
background-color: orange;
|
background-color: orange;
|
||||||
}
|
}
|
||||||
.the-ugly {
|
.the-ugly {
|
||||||
background-color: red;
|
background-color: #ff0000;
|
||||||
}
|
}
|
||||||
.the-draw {
|
.the-draw {
|
||||||
background-color: purple;
|
background-color: #9b02fc;
|
||||||
}
|
}
|
||||||
.the-dead {
|
.the-dead {
|
||||||
background-color: black;
|
background-color: #262626;
|
||||||
}
|
}
|
||||||
/* end visit state classes*/
|
/* end visit state classes*/
|
||||||
|
|
||||||
|
.btn.btn-edit {
|
||||||
|
color: #030303;
|
||||||
|
background-color: #a2a2ec;
|
||||||
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,9 @@ public class ApiConfig
|
||||||
public string ImageUpload { get; set; } = "";
|
public string ImageUpload { get; set; } = "";
|
||||||
public string UserRegistration { get; set; } = "";
|
public string UserRegistration { get; set; } = "";
|
||||||
public string UserInfo { get; set; } = "";
|
public string UserInfo { get; set; } = "";
|
||||||
public string CvrLookup { get; set; } = "";
|
public string BrRegEndpoint { get; set; } = "";
|
||||||
|
public string NoEndpointVat { get; set; } = "";
|
||||||
|
public string ViesEndpoint { get; set; } = "";
|
||||||
public string TokenPath { get; set; } = "";
|
public string TokenPath { get; set; } = "";
|
||||||
public string GlsTrackUrl { get; set; } = "";
|
public string GlsTrackUrl { get; set; } = "";
|
||||||
public string GlsId { get; set; } = "";
|
public string GlsId { get; set; } = "";
|
||||||
|
|
9
Wonky.Entity/Configuration/AppInfo.cs
Normal file
9
Wonky.Entity/Configuration/AppInfo.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Wonky.Entity.Configuration;
|
||||||
|
|
||||||
|
public class AppInfo
|
||||||
|
{
|
||||||
|
public string Version { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Image { get; set; }
|
||||||
|
public bool IsBeta { get; set; }
|
||||||
|
}
|
|
@ -21,10 +21,15 @@ namespace Wonky.Entity.DTO;
|
||||||
|
|
||||||
public class CompanyDto
|
public class CompanyDto
|
||||||
{
|
{
|
||||||
[Required(ErrorMessage = "Navn skal udfyldes")] [MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")] public string Name { get; set; }
|
[Required(ErrorMessage = "Navn skal udfyldes")] [MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
||||||
[Required(ErrorMessage = "Postnummer skal udfyldes")] [MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")] public string ZipCode { get; set; }
|
public string Name { get; set; }
|
||||||
[Required(ErrorMessage = "Bynavn skal udfyldes")] [MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn")] public string City { get; set; }
|
[Required(ErrorMessage = "Postnummer skal udfyldes")] [MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
||||||
[Required(ErrorMessage = "ORG/VAT/CVR er ikke et gyldigt nummer")] public string VatNumber { get; set; }
|
public string ZipCode { get; set; }
|
||||||
|
[Required(ErrorMessage = "Bynavn skal udfyldes")] [MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn")]
|
||||||
|
public string City { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "ORG/VAT/CVR er ikke et gyldigt nummer")]
|
||||||
|
public string VatNumber { get; set; } = "";
|
||||||
public string CompanyId { get; set; } = "";
|
public string CompanyId { get; set; } = "";
|
||||||
public string SalesRepId { get; set; } = "";
|
public string SalesRepId { get; set; } = "";
|
||||||
public string BcId { get; set; } = "";
|
public string BcId { get; set; } = "";
|
||||||
|
@ -35,11 +40,20 @@ public class CompanyDto
|
||||||
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")] public string Mobile { get; set; } = "";
|
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")] public string Mobile { get; set; } = "";
|
||||||
[MaxLength(80, ErrorMessage = "Du kan højst bruge 80 tegn")] public string Email { get; set; } = "";
|
[MaxLength(80, ErrorMessage = "Du kan højst bruge 80 tegn")] public string Email { get; set; } = "";
|
||||||
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")] public string Attention { get; set; } = "";
|
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")] public string Attention { get; set; } = "";
|
||||||
|
public string CountryCode { get; set; } = "";
|
||||||
public string LastVisit { get; set; } = "";
|
public string LastVisit { get; set; } = "";
|
||||||
public string NextVisit { get; set; } = "";
|
public string NextVisit { get; set; } = "";
|
||||||
|
[Range(1, 52, ErrorMessage = "Angiv interval mellem 1 og 52 uger")]
|
||||||
public int Interval { get; set; } = 8;
|
public int Interval { get; set; } = 8;
|
||||||
public int IsHidden { get; set; }
|
|
||||||
public int HasFolded { get; set; }
|
public int HasFolded { get; set; }
|
||||||
|
public int IsHidden { get; set; }
|
||||||
public int ValidVat { get; set; }
|
public int ValidVat { get; set; }
|
||||||
public string CountryCode { get; set; } = "";
|
public int UpdateErpVat { get; set; }
|
||||||
|
public bool ValidDateSpan()
|
||||||
|
{
|
||||||
|
var notAllowed = new List<string> {"1970-01-01", "0001-01-01"};
|
||||||
|
if (notAllowed.Contains(LastVisit) || notAllowed.Contains(NextVisit))
|
||||||
|
return false;
|
||||||
|
return DateTime.Parse(LastVisit) < DateTime.Parse(NextVisit);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,33 +0,0 @@
|
||||||
// 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.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace Wonky.Entity.DTO;
|
|
||||||
|
|
||||||
public class CompanyUpdateDto
|
|
||||||
{
|
|
||||||
public string CompanyId { get; set; } = "";
|
|
||||||
[MaxLength(100)] public string Name { get; set; } = "";
|
|
||||||
[MaxLength(30)] public string City { get; set; } = "";
|
|
||||||
[MaxLength(20)] public string ZipCode { get; set; } = "";
|
|
||||||
[MaxLength(20)] public string VatNumber { get; set; } = "";
|
|
||||||
[MaxLength(30)] public string Phone { get; set; } = "";
|
|
||||||
[MaxLength(100)] public string Address1 { get; set; } = "";
|
|
||||||
[MaxLength(50)] public string Address2 { get; set; } = "";
|
|
||||||
[MaxLength(100)] public string Attention { get; set; } = "";
|
|
||||||
[MaxLength(80)] public string Email { get; set; } = "";
|
|
||||||
[MaxLength(30)] public string Mobile { get; set; } = "";
|
|
||||||
}
|
|
Loading…
Reference in a new issue