added vatNumber validation order - necessary for Sweden

This commit is contained in:
Frede Hundewadt 2023-01-20 06:54:15 +01:00
parent 4591cf156a
commit e170d00f0d
4 changed files with 82 additions and 51 deletions

View file

@ -51,7 +51,7 @@ public class VatUtils
/// </summary>
/// <param name="vatNumber"></param>
/// <returns></returns>
private static string SanitizeVatNumber(string vatNumber)
public static string SanitizeVatNumber(string vatNumber)
{
if (string.IsNullOrWhiteSpace(vatNumber))
return "";

View file

@ -54,9 +54,9 @@ else
<EditForm EditContext="ActivityContext">
<DataAnnotationsValidator/>
<div class="row mb-1">
<label for="activityType" class="col-md-2 col-form-label">Ordre Type</label>
<div class="col-md-4">
<div class="row mb-1 g-2">
<label for="activityType" class="col-sm-2 col-form-label-sm">Ordre Type</label>
<div class="col-sm-4">
<InputSelect id="activityType" class="form-select bg-primary text-bg-primary" @bind-Value="@Activity.ActivityTypeEnum">
<option value="">&rarr; TAG MIG &larr;</option>
<option value="onSite">Besøg</option>
@ -65,8 +65,8 @@ else
<ValidationMessage For="@(() => Activity.ActivityTypeEnum)"></ValidationMessage>
</div>
<label for="statusType" class="col-md-2 col-form-label">Status</label>
<div class="col-md-4">
<label for="statusType" class="col-sm-2 col-form-label-sm">Status</label>
<div class="col-sm-4">
<InputSelect id="statusType" class="form-select bg-primary text-bg-primary" @bind-Value="@Activity.ActivityStatusEnum">
<option value="noSale">Ingen salg</option>
@if (!string.IsNullOrEmpty(Activity.VatNumber) && !string.IsNullOrWhiteSpace(Activity.Address1) && Company.HasFolded == 0)
@ -99,64 +99,75 @@ else
</div>
}
</div>
</div>
<div class="row mb-1">
<label for="demo" class="col-md-2 col-form-label">Demo</label>
<div class="col-md-4">
<label for="demo" class="col-sm-2 col-form-label-sm">Demo</label>
<div class="col-sm-4">
<InputText id="demo" class="form-control" @bind-Value="Activity.Demo"/>
<ValidationMessage For="@(() => Activity.Demo)"></ValidationMessage>
</div>
<label for="email" class="col-md-2 col-form-label">Epost</label>
<div class="col-md-4">
<label for="email" class="col-sm-2 col-form-label-sm">Epost</label>
<div class="col-sm-4">
<InputText id="email" class="form-control" @bind-Value="Activity.Email"/>
<ValidationMessage For="@(() => Activity.Email)"></ValidationMessage>
</div>
</div>
<div class="row mb-1">
<label for="referenceNumber" class="col-md-2 col-form-label">Rekvisition</label>
<div class="col-md-4">
<label for="referenceNumber" class="col-sm-2 col-form-label-sm">Rekvisition</label>
<div class="col-sm-4">
<InputText id="referenceNumber" class="form-control" @bind-Value="Activity.ReferenceNumber"/>
<ValidationMessage For="@(() => Activity.ReferenceNumber)"></ValidationMessage>
</div>
<label for="yourRef" class="col-md-2 col-form-label">Indkøber</label>
<div class="col-md-4">
<label for="yourRef" class="col-sm-2 col-form-label-sm">Indkøber</label>
<div class="col-sm-4">
<InputText id="yourRef" class="form-control" @bind-Value="Activity.YourRef"/>
<ValidationMessage For="@(() => Activity.YourRef)"></ValidationMessage>
</div>
</div>
<div class="row mb-1">
<label for="orderMessage" class="col-md-2 col-form-label">Note /Kontor</label>
<div class="col-md-4">
<label for="orderMessage" class="col-sm-2 col-form-label-sm">Note /Kontor</label>
<div class="col-sm-4">
<InputTextArea id="orderMessage" class="form-control" @bind-Value="Activity.OrderMessage"/>
<ValidationMessage For="@(() => Activity.OrderMessage)"></ValidationMessage>
</div>
<label for="crmNote" class="col-md-2 col-form-label">Note /Selv</label>
<div class="col-md-4">
<label for="crmNote" class="col-sm-2 col-form-label-sm">Note /Selv</label>
<div class="col-sm-4">
<InputTextArea id="crmNote" class="form-control" @bind-Value="Activity.CrmNote"/>
<ValidationMessage For="@(() => Activity.CrmNote)"></ValidationMessage>
</div>
</div>
<div class="row mb-2">
<label for="attention" class="col-md-2 col-form-label">Att.</label>
<div class="col-md-4">
<label for="attention" class="col-sm-2 col-form-label-sm">Att.</label>
<div class="col-sm-4">
<InputText id="attention" class="form-control" @bind-Value="Activity.Attention"/>
<ValidationMessage For="@(() => Activity.Attention)"></ValidationMessage>
</div>
<label for="phone" class="col-md-2 col-form-label">Tlf.</label>
<div class="col-md-4">
<label for="phone" class="col-sm-2 col-form-label-sm">Tlf.</label>
<div class="col-sm-4">
<InputText id="phone" class="form-control" @bind-Value="Activity.Phone"/>
<ValidationMessage For="@(() => Activity.Phone)"></ValidationMessage>
</div>
<label for="vatNumber" class="col-sm-2 col-form-label-sm">Org.nr.</label>
<div class="col-sm-4">
<InputText hidden="vatNumber" class="form-control" @bind-Value="Activity.VatNumber" />
<ValidationMessage For="@(() => Activity.VatNumber)" />
</div>
</div>
<div class="row">
<div class="col-sm-4">
<button class="btn btn-danger">Faktura</button>
</div>
<div class="cols-sm-3">
<button class="btn btn-warning">Tidl. besøg</button>
</div>
<div class="col-sm-4">
<button class="btn btn-success">Produkter</button>
</div>
</div>
<div id="this-draft" style="@(Activity.ActivityStatusEnum is "order" or "quote" ? "display: block" : "display:none")">
@* Draft lines in draft -----------------------------------------------------*@
<div class="row">
@ -280,31 +291,31 @@ else
aria-labelledby="deliveryHeader" data-bs-parent="#crmActivity">
<div class="accordion-body">
<div class="row mb-1">
<label for="dlvName" class="col-md-2 col-form-label">Lev. Navn</label>
<label for="dlvName" class="col-sm-2 col-form-label-sm">Lev. Navn</label>
<div class="col-md-10">
<InputText id="dlvName" class="form-control" @bind-Value="Activity.DlvName"/>
</div>
</div>
<div class="row mb-1">
<label for="dlvAddress1" class="col-md-2 col-form-label">Lev. Adresse</label>
<label for="dlvAddress1" class="col-sm-2 col-form-label-sm">Lev. Adresse</label>
<div class="col-md-10">
<InputText id="dlvAddress1" class="form-control" @bind-Value="Activity.DlvAddress1"/>
</div>
</div>
<div class="row mb-1">
<label for="dlvAddress2" class="col-md-2 col-form-label">Lev. Adresse</label>
<label for="dlvAddress2" class="col-sm-2 col-form-label-sm">Lev. Adresse</label>
<div class="col-md-10">
<InputText id="dlvAddress2" class="form-control" @bind-Value="Activity.DlvAddress2"/>
</div>
</div>
<div class="row mb-1">
<label for="dlvZipCode" class="col-md-2 col-form-label">Lev. Postnr</label>
<label for="dlvZipCode" class="col-sm-2 col-form-label-sm">Lev. Postnr</label>
<div class="col-md-10">
<InputText id="dlvZipCode" class="form-control" @bind-Value="Activity.DlvZipCode"/>
</div>
</div>
<div class="row mb-1">
<label for="dlvCity" class="col-md-2 col-form-label">Lev. Bynavn</label>
<label for="dlvCity" class="col-sm-2 col-form-label-sm">Lev. Bynavn</label>
<div class="col-md-10">
<InputText id="dlvCity" class="form-control" @bind-Value="Activity.DlvCity"/>
</div>

View file

@ -39,7 +39,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
[Inject] private ILogger<AdvisorActivityCreatePage> Logger { get; set; }
[Inject] private HttpInterceptorService Interceptor { get; set; }
[Inject] private UserProfileService Profiles { get; set; }
[Inject] private IToastService Toast { get; set; }
[Inject] private IToastService Toaster { get; set; }
[Inject] private NavigationManager Navigator { get; set; }
[Inject] private ILocalStorageService Storage { get; set; }
[Inject] private ICountryCatalogRepository Catalog { get; set; }
@ -153,6 +153,10 @@ public partial class AdvisorActivityCreatePage : IDisposable
}
Working = false;
//StateHasChanged();
if (Company.CountryCode.ToLower() == "se" && VatUtils.SanitizeVatNumber(Activity.VatNumber).Length < 10)
{
Toaster.ShowWarning("Organisationsnummer skal opdateres.");
}
}
private async Task CallConfirmProductCheckModel()
@ -181,17 +185,17 @@ public partial class AdvisorActivityCreatePage : IDisposable
{
Working = true;
// pop a message
Toast.ShowError("Produkt gennemgang mangler. Vent mens produkt oversigt indlæses. Gå ikke væk fra siden!", "Produkt check ...");
Toaster.ShowError("Produkt gennemgang mangler. Vent mens produkt oversigt indlæses. Gå ikke væk fra siden!", "Produkt check ...");
// product inventory has not been updated
// send rpc call to sync ERP to CRM
Toast.ShowInfo("Vent mens data synkroniseres ...", "ERP til CRM ...");
Toaster.ShowInfo("Vent mens data synkroniseres ...", "ERP til CRM ...");
var ts = await CustomerHistory.InvoiceErpToCrmRpc(CompanyId, Company.HistorySync);
while (string.IsNullOrWhiteSpace(ts))
await Task.Delay(500);
// save pDate
await Storage.SetItemAsync($"{CompanyId}-pDate", ts);
// request products from backend
Toast.ShowInfo("Vent mens produkt oversigt hentes", "CRM produkt liste");
Toaster.ShowInfo("Vent mens produkt oversigt hentes", "CRM produkt liste");
CheckList = await CustomerHistory.FetchInventory(CompanyId);
if(CheckList.Any())
@ -211,6 +215,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
// Show CheckList modal
ConfirmProductCheckModal.Show();
}
private async Task ConfirmProductCheckCallback()
{
ConfirmProductCheckModal.Hide();
@ -297,26 +302,35 @@ public partial class AdvisorActivityCreatePage : IDisposable
// avoid duplication
if (Working)
return;
// validate customer address1 - this is a required input
// validate customer address1
// - this is a required input
if (string.IsNullOrWhiteSpace(Activity.Address1))
{
Toast.ShowError("Kunde adresse er ufuldstændig.");
Toaster.ShowError("Kunde adresse er ufuldstændig.");
return;
}
//
// validate org number
// - this is a required input
// - must validate according to country rules.
if (!VatUtils.ValidateFormat(Company.CountryCode, Activity.VatNumber))
{
Toaster.ShowError("Firma registreringsnummer er ikke korrekt.");
return;
}
// validate input according to status
switch (Activity.ActivityStatusEnum)
{
// don't accept order with no lines
case "order" when DraftProvider.Draft.Items.Count == 0:
Toast.ShowError("Ved bestilling skal der være en eller flere linjer i kladden.");
Toaster.ShowError("Ved bestilling skal der være en eller flere linjer i kladden.");
return;
// phone number is required if first time customer
case "order" when Company.Account is "NY" or "" && string.IsNullOrWhiteSpace(Activity.Phone):
Toast.ShowError("Ved bestilling til ny kunde skal telefon nummer angives.");
Toaster.ShowError("Ved bestilling til ny kunde skal telefon nummer angives.");
return;
// verify email address is a valid address
case "quote" when !Utils.IsValidEmail(Activity.Email):
Toast.ShowError("Ved tilbud skal en gyldig email adresse angives.");
Toaster.ShowError("Ved tilbud skal en gyldig email adresse angives.");
return;
}
// raise working flag
@ -371,7 +385,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
// show result message
if (result.IsSuccess)
{
Toast.ShowSuccess($"{result.Message}",
Toaster.ShowSuccess($"{result.Message}",
DraftProvider.Draft.Items.Count == 0 ? "Besøg er oprettet" : "Bestilling/Tilbud er oprettet");
await DeleteDraft();
Navigator.NavigateTo($"/advisor/customers");
@ -380,7 +394,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
// lower working flag
Working = false;
// show error message
Toast.ShowError(result.Message, "ORDRE FEJL");
Toaster.ShowError(result.Message, "ORDRE FEJL");
}
/// <summary>
@ -481,7 +495,13 @@ public partial class AdvisorActivityCreatePage : IDisposable
{
if (string.IsNullOrEmpty(Activity.ActivityTypeEnum) && !ReportClosed)
{
Toast.ShowWarning("Aktivitet type kan ikke være tom");
Toaster.ShowWarning("Aktivitet type kan ikke være tom");
PoFormInvalid = true;
return;
}
if (Company.CountryCode.ToLower() == "se" && VatUtils.SanitizeVatNumber(Activity.VatNumber).Length < 10)
{
PoFormInvalid = true;
return;
}

View file

@ -1,13 +1,13 @@
{
"appInfo": {
"name": "Wonky Online",
"version": "0.103.xxx",
"version": "0.103.1",
"rc": true,
"sandBox": false,
"image": "grumpy-coder.png"
},
"apiConfig": {
"baseUrl": "https://dev.innotec.dk",
"baseUrl": "https://zeta.innotec.dk",
"catalog": "api/v2/catalog/country",
"crmCustomers": "api/v2/crm/companies",
"crmInventoryExt": "history/inventory",