FEAT: KANVAS customer
This commit is contained in:
parent
0a96c9c640
commit
7572127425
7 changed files with 477 additions and 350 deletions
|
@ -37,7 +37,7 @@
|
||||||
}
|
}
|
||||||
<div class="row mb-2 bg-dark text-white rounded-3 p-3">
|
<div class="row mb-2 bg-dark text-white rounded-3 p-3">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h3>@Activity.Name - @Activity.Account</h3>
|
<span class="h3">@Activity.Name</span> <span>(@Activity.Account)</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -58,9 +58,16 @@ else
|
||||||
<label for="activityType" class="col-sm-2 col-form-label-sm">Ordre Type</label>
|
<label for="activityType" class="col-sm-2 col-form-label-sm">Ordre Type</label>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<InputSelect id="activityType" class="form-select bg-primary text-bg-primary" @bind-Value="@Activity.ActivityTypeEnum">
|
<InputSelect id="activityType" class="form-select bg-primary text-bg-primary" @bind-Value="@Activity.ActivityTypeEnum">
|
||||||
<option value="">→ TAG MIG ←</option>
|
@if (Kanvas)
|
||||||
<option value="onSite">Besøg</option>
|
{
|
||||||
<option value="phone">Telefon</option>
|
<option value="canvas" selected>Kanvas</option>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<option value="">→ TAG MIG ←</option>
|
||||||
|
<option value="onSite">Besøg</option>
|
||||||
|
<option value="phone">Telefon</option>
|
||||||
|
}
|
||||||
</InputSelect>
|
</InputSelect>
|
||||||
<ValidationMessage For="@(() => Activity.ActivityTypeEnum)"></ValidationMessage>
|
<ValidationMessage For="@(() => Activity.ActivityTypeEnum)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
|
@ -68,25 +75,32 @@ else
|
||||||
<label for="statusType" class="col-sm-2 col-form-label-sm">Status</label>
|
<label for="statusType" class="col-sm-2 col-form-label-sm">Status</label>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<InputSelect id="statusType" class="form-select bg-primary text-bg-primary" @bind-Value="@Activity.ActivityStatusEnum">
|
<InputSelect id="statusType" class="form-select bg-primary text-bg-primary" @bind-Value="@Activity.ActivityStatusEnum">
|
||||||
<option value="noSale">Ingen salg</option>
|
@if (Kanvas)
|
||||||
@if (!string.IsNullOrEmpty(Activity.VatNumber) && !string.IsNullOrWhiteSpace(Activity.Address1) && Company.HasFolded == 0)
|
|
||||||
{
|
{
|
||||||
@if (DraftProvider.Draft.DraftType == "order")
|
<option value="canvas" selected>Kanvas</option>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<option value="noSale">Ingen salg</option>
|
||||||
|
@if (!string.IsNullOrEmpty(Activity.VatNumber) && !string.IsNullOrWhiteSpace(Activity.Address1) && Company.HasFolded == 0)
|
||||||
{
|
{
|
||||||
<option selected value="order">Bestilling</option>
|
@if (DraftProvider.Draft.DraftType == "order")
|
||||||
}
|
{
|
||||||
else
|
<option selected value="order">Bestilling</option>
|
||||||
{
|
}
|
||||||
<option value="order">Bestilling</option>
|
else
|
||||||
}
|
{
|
||||||
|
<option value="order">Bestilling</option>
|
||||||
|
}
|
||||||
|
|
||||||
@if (DraftProvider.Draft.DraftType == "offer")
|
@if (DraftProvider.Draft.DraftType == "offer")
|
||||||
{
|
{
|
||||||
<option selected value="quote">Tilbud</option>
|
<option selected value="quote">Tilbud</option>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<option value="quote">Tilbud</option>
|
<option value="quote">Tilbud</option>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</InputSelect>
|
</InputSelect>
|
||||||
|
@ -156,6 +170,8 @@ else
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if (!Kanvas)
|
||||||
|
{
|
||||||
<div class="row g-2 mb-3">
|
<div class="row g-2 mb-3">
|
||||||
<div class="col-sm-3 d-grid mx-auto">
|
<div class="col-sm-3 d-grid mx-auto">
|
||||||
@*
|
@*
|
||||||
|
@ -348,7 +364,9 @@ else
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
</EditForm>
|
</EditForm>
|
||||||
|
|
||||||
<div class="row mt-5 mb-2">
|
<div class="row mt-5 mb-2">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<a class="btn btn-warning" href="/advisor/customers/@Company.CompanyId">Kundekort <i class="bi-arrow-left"></i></a>
|
<a class="btn btn-warning" href="/advisor/customers/@Company.CompanyId">Kundekort <i class="bi-arrow-left"></i></a>
|
||||||
|
|
|
@ -96,6 +96,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
private List<ProductInventoryView> CheckList { get; set; } = new();
|
private List<ProductInventoryView> CheckList { get; set; } = new();
|
||||||
private InvoiceListView CompanyInvoices { get; set; } = new();
|
private InvoiceListView CompanyInvoices { get; set; } = new();
|
||||||
private List<ReportItemView> Activities { get; set; } = new();
|
private List<ReportItemView> Activities { get; set; } = new();
|
||||||
|
private bool Kanvas { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Page initialization
|
/// Page initialization
|
||||||
|
@ -114,23 +115,35 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
SalesRep = await UserInfo.GetUserInfo();
|
SalesRep = await UserInfo.GetUserInfo();
|
||||||
// Fetch Customer from http
|
// Fetch Customer from http
|
||||||
Company = await CompanyRepo.GetCompanyById(CompanyId);
|
Company = await CompanyRepo.GetCompanyById(CompanyId);
|
||||||
if (Company.HasFolded == 1)
|
if (Company.Account.StartsWith("KANVAS"))
|
||||||
// Company has shut down
|
|
||||||
Activity.OrderMessage = "BEMÆRK: CVR nummer er ophørt.";
|
|
||||||
|
|
||||||
// variable to validate if customer needs phone number update
|
|
||||||
OldPhone = Company.Phone;
|
|
||||||
if (string.IsNullOrWhiteSpace(Company.Phone)
|
|
||||||
&& !string.IsNullOrWhiteSpace(Company.Account)
|
|
||||||
&& Company.Account != "NY" && Company.Account.Length > 7)
|
|
||||||
{
|
{
|
||||||
Company.Phone = Company.Account[..8];
|
Kanvas = true;
|
||||||
|
|
||||||
|
Activity.ActivityStatusEnum = "canvas";
|
||||||
|
Activity.ActivityTypeEnum = "canvas";
|
||||||
|
Activity.ActivityVisitEnum = "new";
|
||||||
|
PoFormInvalid = false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Company.HasFolded == 1)
|
||||||
|
// Company has shut down
|
||||||
|
Activity.OrderMessage = "BEMÆRK: CVR nummer er ophørt.";
|
||||||
|
|
||||||
|
// variable to validate if customer needs phone number update
|
||||||
|
OldPhone = Company.Phone;
|
||||||
|
if (string.IsNullOrWhiteSpace(Company.Phone)
|
||||||
|
&& !string.IsNullOrWhiteSpace(Company.Account)
|
||||||
|
&& Company.Account != "NY" && Company.Account.Length > 7)
|
||||||
|
{
|
||||||
|
Company.Phone = Company.Account[..8];
|
||||||
|
}
|
||||||
|
Activity.ActivityStatusEnum = "noSale";
|
||||||
|
Activity.ActivityVisitEnum = Company.Account is "" or "NY" ? "new" : "recall";
|
||||||
|
}
|
||||||
|
|
||||||
// Populate base activity information
|
// Populate base activity information
|
||||||
Activity.BcId = Company.BcId;
|
Activity.BcId = Company.BcId;
|
||||||
Activity.ActivityStatusEnum = "noSale";
|
|
||||||
Activity.VisitTypeEnum = Company.Account is "" or "NY" ? "new" : "recall";
|
|
||||||
Activity.CompanyId = Company.CompanyId;
|
Activity.CompanyId = Company.CompanyId;
|
||||||
Activity.SalesRepId = SalesRep.UserId;
|
Activity.SalesRepId = SalesRep.UserId;
|
||||||
Activity.SalesRep = SalesRep.SalesRep;
|
Activity.SalesRep = SalesRep.SalesRep;
|
||||||
|
@ -164,12 +177,14 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
PromptDateConfirm = $"Aktiviteter oprettes med dato {SelectedDate.ToShortDateString()}. Er dette OK?";
|
PromptDateConfirm = $"Aktiviteter oprettes med dato {SelectedDate.ToShortDateString()}. Er dette OK?";
|
||||||
ConfirmWorkDate.Show();
|
ConfirmWorkDate.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lines may already have been added from the company inventory page
|
// Lines may already have been added from the company inventory page
|
||||||
if (DraftProvider.Draft.DraftType == "order")
|
if (DraftProvider.Draft.DraftType == "order")
|
||||||
{
|
{
|
||||||
// set dropdown selection accordingly
|
// set dropdown selection accordingly
|
||||||
Activity.ActivityTypeEnum = "onSite";
|
if(Activity.ActivityTypeEnum != "phone")
|
||||||
|
Activity.ActivityTypeEnum = "onSite";
|
||||||
|
|
||||||
Activity.ActivityStatusEnum = "order";
|
Activity.ActivityStatusEnum = "order";
|
||||||
PoFormInvalid = false;
|
PoFormInvalid = false;
|
||||||
}
|
}
|
||||||
|
@ -177,91 +192,50 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
Working = false;
|
Working = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #############################################################
|
||||||
|
// overlays
|
||||||
private async Task ShowVisitOverlay()
|
private async Task ShowVisitOverlay()
|
||||||
{
|
{
|
||||||
Logger.LogDebug("ShowInventoryOverlay - wait for visits");
|
Logger.LogDebug("ShowInventoryOverlay - wait for visits");
|
||||||
|
|
||||||
ActivityListOverlay.Show();
|
ActivityListOverlay.Show();
|
||||||
|
|
||||||
Activities = await ActivityRepo.GetCustomerActivities(CompanyId);
|
Activities = await ActivityRepo.GetCustomerActivities(CompanyId);
|
||||||
|
|
||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task ShowInventoryOverlay()
|
private async Task ShowInventoryOverlay()
|
||||||
{
|
{
|
||||||
Logger.LogDebug("ShowInventoryOverlay - wait for inventory");
|
Logger.LogDebug("ShowInventoryOverlay - wait for inventory");
|
||||||
|
|
||||||
InventoryListOverlay.Show();
|
InventoryListOverlay.Show();
|
||||||
|
|
||||||
Inventory = await HistoryRepo.FetchInventory(CompanyId);
|
Inventory = await HistoryRepo.FetchInventory(CompanyId);
|
||||||
Inventory = Inventory.OrderBy(x => x.Description).ToList();
|
Inventory = Inventory.OrderBy(x => x.Description).ToList();
|
||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnInventoryCallback(DraftItem item)
|
|
||||||
{
|
|
||||||
Activity.ActivityStatusEnum = "order";
|
|
||||||
DraftProvider.Draft.DraftType = "order";
|
|
||||||
DraftProvider.Draft.Items.Add(item);
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ShowInvoiceOverlay()
|
private async Task ShowInvoiceOverlay()
|
||||||
{
|
{
|
||||||
Logger.LogDebug("ShowInvoiceOverlay - wait for invoices");
|
Logger.LogDebug("ShowInvoiceOverlay - wait for invoices");
|
||||||
|
|
||||||
InvoiceListOverlay.Show();
|
InvoiceListOverlay.Show();
|
||||||
CompanyInvoices = await FetchCompanyInvoices();
|
CompanyInvoices = await FetchCompanyInvoices();
|
||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<InvoiceListView> FetchCompanyInvoices()
|
|
||||||
|
private void ShowPriceListOverlay()
|
||||||
{
|
{
|
||||||
// fetch from storage
|
CatalogOverlay.Show();
|
||||||
var storage = await Storage.GetItemAsStringAsync($"{CompanyId}-invoices");
|
|
||||||
await Task.Delay(500);
|
|
||||||
var iDate = await Storage.GetItemAsStringAsync($"{CompanyId}-iDate");
|
|
||||||
|
|
||||||
// if we have a list and iDate was today return the list
|
|
||||||
if (!string.IsNullOrWhiteSpace(storage) && (!string.IsNullOrWhiteSpace(iDate) &&
|
|
||||||
DateTime.Parse(iDate.Replace("\"", "")) >= DateTime.Now))
|
|
||||||
{
|
|
||||||
Logger.LogDebug("fetching invoices from storage");
|
|
||||||
Logger.LogDebug("storage contains <= {}", storage);
|
|
||||||
return JsonSerializer.Deserialize<InvoiceListView>(storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.LogDebug("pulling invoices from backend");
|
|
||||||
// pull invoices
|
|
||||||
var companyInvoices = await HistoryRepo.FetchInvoiceList(CompanyId);
|
|
||||||
// send invoices to storage
|
|
||||||
await Storage.SetItemAsync($"{CompanyId}-invoices", companyInvoices);
|
|
||||||
await Storage.SetItemAsync($"{CompanyId}-iDate", $"{DateTime.Now:yyyy-MM-dd}");
|
|
||||||
Logger.LogDebug(" --> return invoices from backend");
|
|
||||||
Working = false;
|
|
||||||
Logger.LogDebug("backend contains <= {}", JsonSerializer.Serialize(companyInvoices));
|
|
||||||
return companyInvoices;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowOrgWarning()
|
|
||||||
{
|
|
||||||
if (OrgWarning)
|
|
||||||
return;
|
|
||||||
OrgWarning = true;
|
|
||||||
if (Company.CountryCode.ToLower() == "se" && Utils.StringToDigits(Activity.VatNumber).Length < 10 &&
|
|
||||||
Activity.ActivityStatusEnum == "order")
|
|
||||||
{
|
|
||||||
Toaster.ShowWarning("Org nummer er ufuldstændig. Skal opdateres før bestilling kan sendes. ", "ADVARSEL");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task CallConfirmCheckOverlay()
|
private async Task CallConfirmCheckOverlay()
|
||||||
{
|
{
|
||||||
// check if new account
|
// check if new account
|
||||||
if (string.IsNullOrWhiteSpace(Company.Account)
|
if (string.IsNullOrWhiteSpace(Company.Account)
|
||||||
|| Company.Account.ToLower() == "ny"
|
|| Company.Account.ToLower() == "ny"
|
||||||
|| Activity.ActivityStatusEnum.ToLower() == "quote")
|
|| Activity.ActivityStatusEnum.ToLower() == "quote"
|
||||||
|
|| Activity.ActivityStatusEnum.ToLower() == "canvas")
|
||||||
{
|
{
|
||||||
// proceed to create activity - as there is no product check to be done
|
// proceed to create activity - as there is no product check to be done
|
||||||
await CreateActivity();
|
await CreateActivity();
|
||||||
|
@ -316,38 +290,16 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
ConfirmationCheckOverlay.Show();
|
ConfirmationCheckOverlay.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ConfirmProductCheckCallback()
|
|
||||||
{
|
|
||||||
ConfirmationCheckOverlay.Hide();
|
|
||||||
await CreateActivity();
|
|
||||||
foreach (var item in CheckList)
|
|
||||||
{
|
|
||||||
item.Check = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
await Storage.SetItemAsync($"{CompanyId}-products", CheckList);
|
private void ShowPriceHistoryOverlay()
|
||||||
}
|
{
|
||||||
|
if (ShowItem)
|
||||||
private async Task WorkDateConfirmCallback()
|
PriceOverlay.Show();
|
||||||
{
|
|
||||||
await PreferenceService.SetDateConfirmed(true);
|
|
||||||
Activity.ActivityDate = $"{SelectedDate:yyyy-MM-dd}";
|
|
||||||
ConfirmWorkDate.Hide();
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task WorkDateComponentCallback(string workDate)
|
|
||||||
{
|
|
||||||
ReportClosed = await ReportRepo.ReportExist(workDate);
|
|
||||||
SelectedDate = DateTime.Parse(workDate);
|
|
||||||
Activity.ActivityDate = workDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowPriceListOverlay()
|
|
||||||
{
|
|
||||||
CatalogOverlay.Show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #############################################################
|
||||||
|
// callbacks
|
||||||
private async Task PriceListCallback(SelectedSku sku)
|
private async Task PriceListCallback(SelectedSku sku)
|
||||||
{
|
{
|
||||||
// get selected item
|
// get selected item
|
||||||
|
@ -360,12 +312,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowPriceHistoryOverlay()
|
|
||||||
{
|
|
||||||
if (ShowItem)
|
|
||||||
PriceOverlay.Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PriceHistoryCallback(decimal price)
|
private void PriceHistoryCallback(decimal price)
|
||||||
{
|
{
|
||||||
if (price == 0)
|
if (price == 0)
|
||||||
|
@ -374,26 +321,99 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void OnInventoryCallback(DraftItem item)
|
||||||
|
{
|
||||||
|
Activity.ActivityStatusEnum = "order";
|
||||||
|
DraftProvider.Draft.DraftType = "order";
|
||||||
|
DraftProvider.Draft.Items.Add(item);
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task ConfirmProductCheckCallback()
|
||||||
|
{
|
||||||
|
ConfirmationCheckOverlay.Hide();
|
||||||
|
await CreateActivity();
|
||||||
|
foreach (var item in CheckList)
|
||||||
|
{
|
||||||
|
item.Check = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Storage.SetItemAsync($"{CompanyId}-products", CheckList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task WorkDateConfirmCallback()
|
||||||
|
{
|
||||||
|
await PreferenceService.SetDateConfirmed(true);
|
||||||
|
Activity.ActivityDate = $"{SelectedDate:yyyy-MM-dd}";
|
||||||
|
ConfirmWorkDate.Hide();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task WorkDateComponentCallback(string workDate)
|
||||||
|
{
|
||||||
|
ReportClosed = await ReportRepo.ReportExist(workDate);
|
||||||
|
SelectedDate = DateTime.Parse(workDate);
|
||||||
|
Activity.ActivityDate = workDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ################################################################################################
|
||||||
|
// fetch invoices for customer
|
||||||
|
private async Task<InvoiceListView> FetchCompanyInvoices()
|
||||||
|
{
|
||||||
|
// no need to do for kanvas entry
|
||||||
|
if (Kanvas) return new InvoiceListView();
|
||||||
|
// fetch from storage
|
||||||
|
var storage = await Storage.GetItemAsStringAsync($"{CompanyId}-invoices");
|
||||||
|
await Task.Delay(500);
|
||||||
|
var iDate = await Storage.GetItemAsStringAsync($"{CompanyId}-iDate");
|
||||||
|
// if we have a list and iDate was today return the list
|
||||||
|
if (!string.IsNullOrWhiteSpace(storage) && (!string.IsNullOrWhiteSpace(iDate) &&
|
||||||
|
DateTime.Parse(iDate.Replace("\"", "")) >= DateTime.Now))
|
||||||
|
{
|
||||||
|
Logger.LogDebug("fetching invoices from storage");
|
||||||
|
Logger.LogDebug("storage contains <= {}", storage);
|
||||||
|
return JsonSerializer.Deserialize<InvoiceListView>(storage);
|
||||||
|
}
|
||||||
|
Logger.LogDebug("pulling invoices from backend");
|
||||||
|
// pull invoices
|
||||||
|
var companyInvoices = await HistoryRepo.FetchInvoiceList(CompanyId);
|
||||||
|
// send invoices to storage
|
||||||
|
await Storage.SetItemAsync($"{CompanyId}-invoices", companyInvoices);
|
||||||
|
await Storage.SetItemAsync($"{CompanyId}-iDate", $"{DateTime.Now:yyyy-MM-dd}");
|
||||||
|
Logger.LogDebug(" --> return invoices from backend");
|
||||||
|
Working = false;
|
||||||
|
Logger.LogDebug("backend contains <= {}", JsonSerializer.Serialize(companyInvoices));
|
||||||
|
return companyInvoices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ##################################################################################################
|
||||||
|
// create activity
|
||||||
private async Task CreateActivity()
|
private async Task CreateActivity()
|
||||||
{
|
{
|
||||||
// avoid duplication
|
// avoid duplication
|
||||||
if (Working)
|
if (Working)
|
||||||
return;
|
return;
|
||||||
// validate customer address1
|
|
||||||
// - this is a required input
|
Logger.LogDebug("view kanvas activity => {}", JsonSerializer.Serialize(Activity));
|
||||||
if (string.IsNullOrWhiteSpace(Activity.Address1))
|
switch (Kanvas)
|
||||||
{
|
{
|
||||||
Toaster.ShowError("Kunde adresse er ufuldstændig.");
|
// validate customer address1
|
||||||
return;
|
// - this is a required input
|
||||||
}
|
case false when string.IsNullOrWhiteSpace(Activity.Address1):
|
||||||
|
Toaster.ShowError("Kunde adresse er ufuldstændig.");
|
||||||
// validate org number
|
return;
|
||||||
// - this is a required input
|
// validate org number
|
||||||
// - must validate according to country rules.
|
// - this is a required input
|
||||||
if (!VatUtils.ValidateFormat(Company.CountryCode, Activity.VatNumber))
|
// - must validate according to country rules.
|
||||||
{
|
case false when !VatUtils.ValidateFormat(Company.CountryCode, Activity.VatNumber):
|
||||||
Toaster.ShowError("Firma registreringsnummer er ikke korrekt.");
|
Toaster.ShowError("Firma registreringsnummer er ikke korrekt.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate input according to status
|
// validate input according to status
|
||||||
|
@ -419,7 +439,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
// reset selected item
|
// reset selected item
|
||||||
SelectedItem = new SalesItemView();
|
SelectedItem = new SalesItemView();
|
||||||
// check if phone number need to be updated
|
// check if phone number need to be updated
|
||||||
if (OldPhone != Activity.Phone)
|
if (!Kanvas && OldPhone != Activity.Phone)
|
||||||
{
|
{
|
||||||
Company.Phone = Activity.Phone;
|
Company.Phone = Activity.Phone;
|
||||||
Activity.OrderMessage = $"BEMÆRK: {Activity.Phone}\n{Activity.OrderMessage}";
|
Activity.OrderMessage = $"BEMÆRK: {Activity.Phone}\n{Activity.OrderMessage}";
|
||||||
|
@ -482,12 +502,29 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
Toaster.ShowError(result.Message, "ORDRE FEJL");
|
Toaster.ShowError(result.Message, "ORDRE FEJL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ShowOrgWarning()
|
||||||
|
{
|
||||||
|
if (Kanvas) return;
|
||||||
|
if (OrgWarning) return;
|
||||||
|
OrgWarning = true;
|
||||||
|
if (Company.CountryCode.ToLower() == "se" && Utils.StringToDigits(Activity.VatNumber).Length < 10 &&
|
||||||
|
Activity.ActivityStatusEnum == "order")
|
||||||
|
{
|
||||||
|
Toaster.ShowWarning("Org nummer er ufuldstændig. Skal opdateres før bestilling kan sendes. ", "ADVARSEL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ###############################################################################
|
||||||
|
// draft functions
|
||||||
private async Task DeleteDraft()
|
private async Task DeleteDraft()
|
||||||
{
|
{
|
||||||
await DraftProvider.DeleteDraftAsync();
|
await DraftProvider.DeleteDraftAsync();
|
||||||
Activity.ActivityStatusEnum = "noSale";
|
Activity.ActivityStatusEnum = "noSale";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task AddItem(SalesItemView salesItem)
|
private async Task AddItem(SalesItemView salesItem)
|
||||||
{
|
{
|
||||||
ShowItem = false;
|
ShowItem = false;
|
||||||
|
@ -513,6 +550,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
await DraftProvider.SaveChangesAsync();
|
await DraftProvider.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task RemoveItem(DraftItem item)
|
private async Task RemoveItem(DraftItem item)
|
||||||
{
|
{
|
||||||
// remove item
|
// remove item
|
||||||
|
@ -523,6 +561,9 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
Activity.ActivityStatusEnum = "noSale";
|
Activity.ActivityStatusEnum = "noSale";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ##################################################################################################
|
||||||
|
// form validation
|
||||||
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
||||||
{
|
{
|
||||||
Logger.LogDebug("ActivityNewPage => HandleFieldChanged => ActivityStatusEnum <= '{}'",
|
Logger.LogDebug("ActivityNewPage => HandleFieldChanged => ActivityStatusEnum <= '{}'",
|
||||||
|
@ -556,6 +597,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(Activity.ActivityTypeEnum) && !ReportClosed)
|
if (string.IsNullOrEmpty(Activity.ActivityTypeEnum) && !ReportClosed)
|
||||||
|
@ -582,6 +624,9 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
||||||
ActivityContext.OnValidationStateChanged += ValidationChanged;
|
ActivityContext.OnValidationStateChanged += ValidationChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #########################################################################################################
|
||||||
|
// dispose
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Interceptor.DisposeEvent();
|
Interceptor.DisposeEvent();
|
||||||
|
|
|
@ -29,7 +29,9 @@
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<div class="row pt-2 mb-2 rounded rounded-2 bg-dark text-white">
|
<div class="row pt-2 mb-2 rounded rounded-2 bg-dark text-white">
|
||||||
<h3>@Company.Name @(string.IsNullOrWhiteSpace(Company.Account) ? "" : "- ")@Company.Account</h3>
|
<div class="col-sm-12">
|
||||||
|
<span class="h3">@Company.Name</span> <span>(@Company.Account)</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
// erp context
|
// erp context
|
||||||
<EditForm EditContext="ErpContext">
|
<EditForm EditContext="ErpContext">
|
||||||
|
@ -89,65 +91,81 @@
|
||||||
<InputText id="email" class="form-control" @bind-Value="Company.Email" readonly="@(ErpEditDisabled)"/>
|
<InputText id="email" class="form-control" @bind-Value="Company.Email" readonly="@(ErpEditDisabled)"/>
|
||||||
<ValidationMessage For="@(() => Company.Email)"></ValidationMessage>
|
<ValidationMessage For="@(() => Company.Email)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">@* ---- placeholder --- *@</div>
|
|
||||||
@* Force enable visit *@
|
@if (!Kanvas)
|
||||||
<div class="col-sm-3 d-grid mx-auto">
|
{
|
||||||
<button type="button" class="btn btn-primary d-block" disabled="@(Company.HasFolded == 0 || Company.Name == "ERROR")" @onclick="ForceActivity">Aktiver besøg</button>
|
<div class="col-sm-4">@* ---- placeholder --- *@</div>
|
||||||
</div>
|
|
||||||
@* Enable edit/save *@
|
@* Enable edit/save *@
|
||||||
<div class="col-sm-2 d-grid mx-auto">
|
<div class="col-sm-2 d-grid mx-auto">
|
||||||
<button type="button" class="btn btn-edit" @onclick="ToggleErpEdit"><i class="bi-pencil"></i> STAM data</button>
|
<button type="button" class="btn btn-edit" @onclick="ToggleErpEdit"><i class="bi-pencil"></i> STAM data</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3 d-grid mx-auto">
|
@* Force enable visit *@
|
||||||
<button type="button" class="btn btn-danger d-block" onclick="@UpdateErpData" disabled="@(Working || Company.Name == "ERROR" || ErpEditDisabled)"><i class="bi-cloud-arrow-up"></i> STAM data </button>
|
<div class="col-sm-3 d-grid mx-auto">
|
||||||
</div>
|
<button type="button" class="btn btn-primary d-block" @onclick="ForceActivity">Aktiver besøg</button>
|
||||||
@* vat number*@
|
</div>
|
||||||
<label for="vatNumber" class="col-sm-1 col-form-label-sm">CVR/Org nr.</label>
|
@* Save erp data *@
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3 d-grid mx-auto">
|
||||||
<div class="input-group">
|
<button type="button" class="btn btn-danger d-block" onclick="@UpdateErpData" disabled="@(Working || Company.Name == "ERROR" || ErpEditDisabled)"><i class="bi-cloud-arrow-up"></i> STAM data </button>
|
||||||
<span class="input-group-text">
|
</div>
|
||||||
<DisplayStateComponent StateClass="@VatState"/>
|
@* vat number*@
|
||||||
</span>
|
<label for="vatNumber" class="col-sm-1 col-form-label-sm">CVR/Org nr.</label>
|
||||||
<InputText id="vatNumber" class="form-control" @bind-Value="Company.VatNumber" readonly="@(VatEditDisabled)"/>
|
<div class="col-sm-3">
|
||||||
<ValidationMessage For="@(() => Company.VatNumber)"></ValidationMessage>
|
<div class="input-group">
|
||||||
|
<span class="input-group-text">
|
||||||
|
<DisplayStateComponent StateClass="@VatState"/>
|
||||||
|
</span>
|
||||||
|
<InputText id="vatNumber" class="form-control" @bind-Value="Company.VatNumber" readonly="@(VatEditDisabled)"/>
|
||||||
|
<ValidationMessage For="@(() => Company.VatNumber)"></ValidationMessage>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@* Enable edit/save vatnumber *@
|
||||||
|
<div class="col-sm-2 d-grid mx-auto">
|
||||||
|
<button type="button" class="btn btn-edit" @onclick="ToggleVatEdit"><i class="bi-pencil"></i> Moms/Org Nr.</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
@* vat lookup *@
|
@* vat lookup *@
|
||||||
<div class="col-sm-3 d-grid mx-auto">
|
<div class="col-sm-3 d-grid mx-auto">
|
||||||
@switch (CountryCode)
|
@switch (CountryCode)
|
||||||
{
|
{
|
||||||
case "dk":
|
case "dk":
|
||||||
<button type="button" class="btn btn-info" @onclick="OpenVatLookupModal"><i class="bi-search"></i> CVR</button>
|
<button type="button" class="btn btn-info" @onclick="OpenVatLookupModal" disabled="@(VatEditDisabled)"><i class="bi-search"></i> CVR</button>
|
||||||
break;
|
break;
|
||||||
case "no":
|
case "no":
|
||||||
<a class="btn btn-info" href="https://brreg.no/" target="_blank"><i class="bi-search"></i> brreg.no</a>
|
<a class="btn btn-info" href="https://brreg.no/" target="_blank"><i class="bi-search"></i> brreg.no</a>
|
||||||
break;
|
break;
|
||||||
case "se":
|
case "se":
|
||||||
<a class="btn btn-info" href="https://www.allabolag.se/what/@Company.Name" target="_blank"><i class="bi-search"></i> allabolag.se</a>
|
<a class="btn btn-info" href="https://www.allabolag.se/what/@Company.Name" target="_blank"><i class="bi-search"></i> allabolag.se</a>
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@* Enable edit/save *@
|
|
||||||
<div class="col-sm-2 d-grid mx-auto">
|
|
||||||
<button type="button" class="btn btn-edit" @onclick="ToggleVatEdit"><i class="bi-pencil"></i> Moms/Org Nr.</button>
|
|
||||||
</div>
|
|
||||||
@* save vat number *@
|
@* save vat number *@
|
||||||
<div class="col-sm-3 d-grid mx-auto">
|
<div class="col-sm-3 d-grid mx-auto">
|
||||||
<button type="button" class="btn btn-warning d-block" @onclick="UpdateVatNumber" disabled="@(VatEditDisabled)"><i class="bi-cloud-arrow-up"></i> Moms/Org Nr.</button>
|
<button type="button" class="btn btn-warning d-block" @onclick="UpdateVatNumber" disabled="@(VatEditDisabled)"><i class="bi-cloud-arrow-up"></i> Moms/Org Nr.</button>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class="mb-3"/>
|
<hr class="mb-3"/>
|
||||||
@* activity buttons *@
|
@* activity buttons *@
|
||||||
<div class="row mt-3 mb-3">
|
<div class="row mt-3 mb-3">
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<a class="btn btn-danger d-block" href="/advisor/customers/@Company.CompanyId/invoices">Faktura</a>
|
@if (!Kanvas)
|
||||||
|
{
|
||||||
|
<a class="btn btn-danger d-block" href="/advisor/customers/@Company.CompanyId/invoices">Faktura</a>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<a class="btn btn-warning d-block" href="/advisor/customers/@Company.CompanyId/activities">Tidl. Besøg</a>
|
@if (!Kanvas)
|
||||||
|
{
|
||||||
|
<a class="btn btn-warning d-block" href="/advisor/customers/@Company.CompanyId/activities">Tidl. Besøg</a>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<a class="btn btn-success d-block" href="/advisor/customers/@Company.CompanyId/h/i">Produkter</a>
|
@if (!Kanvas)
|
||||||
|
{
|
||||||
|
<a class="btn btn-success d-block" href="/advisor/customers/@Company.CompanyId/h/i">Produkter</a>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<ActivityButton ActionLink="@ActionLink"
|
<ActivityButton ActionLink="@ActionLink"
|
||||||
|
@ -158,104 +176,105 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class="mb-3"/>
|
@if (!Kanvas)
|
||||||
|
{
|
||||||
|
<hr class="mb-3"/>
|
||||||
@* crm context - OBS note *@
|
@* crm context - OBS note *@
|
||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<label for="note" class="col-sm-1 col-form-label-sm">OBS</label>
|
<label for="note" class="col-sm-1 col-form-label-sm">OBS</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
@if (string.IsNullOrWhiteSpace(Company.Note))
|
@if (string.IsNullOrWhiteSpace(Company.Note))
|
||||||
{
|
|
||||||
<InputText name="note" id="note" class="form-control" @bind-Value="Company.Note"/>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<InputText name="note" id="note" class="form-control bg-warning text-black" @bind-Value="Company.Note"/>
|
|
||||||
}
|
|
||||||
<ValidationMessage For="@(() => Company.Note)"></ValidationMessage>
|
|
||||||
</div>
|
|
||||||
@* Save CRM data button *@
|
|
||||||
<div class="col-sm-3 d-grid mx-auto">
|
|
||||||
<button type="button" class="btn btn-warning" disabled="@(Company.Name == "ERROR")" @onclick="UpdateCrmData"><i class="bi-cloud-arrow-up"></i> CRM data</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@* crm context - contacts *@
|
|
||||||
<div class="row mb-4">
|
|
||||||
<label for="contacts" class="col-sm-1 col-form-label-sm">Kontakt</label>
|
|
||||||
<div id="contacts" class="col-sm-11">
|
|
||||||
<div class="list-group">
|
|
||||||
<div class="list-group-item list-group-item-action bg-dark text-white" @onclick="() => OpenContactPopup(DefaultContact)">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">Stilling</div>
|
|
||||||
<div class="col-sm-4">Navn</div>
|
|
||||||
<div class="col-sm-3">Direkte</div>
|
|
||||||
<div class="col-sm-1 text-end">
|
|
||||||
<i class="bi-plus-circle"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@if (Contacts.Any())
|
|
||||||
{
|
{
|
||||||
@foreach (var contact in Contacts)
|
<InputText name="note" id="note" class="form-control" @bind-Value="Company.Note"/>
|
||||||
{
|
}
|
||||||
<div class="list-group-item list-group-item-action" @onclick="() => OpenContactPopup(contact)">
|
else
|
||||||
<div class="row g-2">
|
{
|
||||||
<div class="col-sm-4">@contact.JobTitle</div>
|
<InputText name="note" id="note" class="form-control bg-warning text-black" @bind-Value="Company.Note"/>
|
||||||
<div class="col-sm-4">@contact.FirstName @contact.LastName</div>
|
}
|
||||||
<div class="col-sm-3">
|
<ValidationMessage For="@(() => Company.Note)"></ValidationMessage>
|
||||||
@contact.PhoneDirect
|
</div>
|
||||||
</div>
|
@* Save CRM data button *@
|
||||||
<div class="col-sm-1 text-end">
|
<div class="col-sm-3 d-grid mx-auto">
|
||||||
<i class="bi-pencil"></i>
|
<button type="button" class="btn btn-warning" disabled="@(Company.Name == "ERROR")" @onclick="UpdateCrmData"><i class="bi-cloud-arrow-up"></i> CRM data</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
@* crm context - contacts *@
|
||||||
|
<div class="row mb-4">
|
||||||
|
<label for="contacts" class="col-sm-1 col-form-label-sm">Kontakt</label>
|
||||||
|
<div id="contacts" class="col-sm-11">
|
||||||
|
<div class="list-group">
|
||||||
|
<div class="list-group-item list-group-item-action bg-dark text-white" @onclick="() => OpenContactPopup(DefaultContact)">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4">Stilling</div>
|
||||||
|
<div class="col-sm-4">Navn</div>
|
||||||
|
<div class="col-sm-3">Direkte</div>
|
||||||
|
<div class="col-sm-1 text-end">
|
||||||
|
<i class="bi-plus-circle"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
@if (Contacts.Any())
|
||||||
|
{
|
||||||
|
@foreach (var contact in Contacts)
|
||||||
|
{
|
||||||
|
<div class="list-group-item list-group-item-action" @onclick="() => OpenContactPopup(contact)">
|
||||||
|
<div class="row g-2">
|
||||||
|
<div class="col-sm-4">@contact.JobTitle</div>
|
||||||
|
<div class="col-sm-4">@contact.FirstName @contact.LastName</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
@contact.PhoneDirect
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-1 text-end">
|
||||||
|
<i class="bi-pencil"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
@* crm context - dates and interval *@
|
@* crm context - dates and interval *@
|
||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<label for="nextVisit" class="col-sm-1 col-form-label-sm">Næste besøg</label>
|
<label for="nextVisit" class="col-sm-1 col-form-label-sm">Næste besøg</label>
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-text">
|
<span class="input-group-text">
|
||||||
<DisplayStateComponent StateClass="@VisitState"/>
|
<DisplayStateComponent StateClass="@VisitState"/>
|
||||||
</span>
|
</span>
|
||||||
<InputDate id="nextVisit" class="form-control" @bind-Value="@(NextVisit)"/>
|
<InputDate id="nextVisit" class="form-control" @bind-Value="@(NextVisit)"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<label for="lastVisit" class="col-sm-1 col-form-label-sm">Sidse besøg</label>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<InputDate id="lastVisit" class="form-control" @bind-Value="@LastVisit"/>
|
||||||
|
</div>
|
||||||
|
<label for="interval" class="col-sm-2 col-form-label-sm">Uge Interval</label>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<InputNumber id="interval" class="form-control" @bind-Value="Company.Interval"/>
|
||||||
|
<ValidationMessage For="@(() => Company.Interval)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<label for="lastVisit" class="col-sm-1 col-form-label-sm">Sidse besøg</label>
|
<div class="row mb-2">
|
||||||
<div class="col-sm-3">
|
<label for="crmNotes" class="col-sm-1 col-form-label-sm">Noter</label>
|
||||||
<InputDate id="lastVisit" class="form-control" @bind-Value="@LastVisit"/>
|
<div class="col-sm-11">
|
||||||
|
<InputTextArea id="crmNotes" class="form-control" @bind-Value="Company.CrmNotes"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<label for="interval" class="col-sm-2 col-form-label-sm">Uge Interval</label>
|
<div class="row pt-3">
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-3 d-grid">
|
||||||
<InputNumber id="interval" class="form-control" @bind-Value="Company.Interval"/>
|
<button type="button" class="btn btn-danger" @onclick="ToggleVisibility">@ToggleButtonText</button>
|
||||||
<ValidationMessage For="@(() => Company.Interval)"></ValidationMessage>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@*
|
||||||
<div class="row mb-2">
|
<div class="row mt-5">
|
||||||
<label for="crmNotes" class="col-sm-1 col-form-label-sm">Noter</label>
|
<div class="col-sm-3">
|
||||||
<div class="col-sm-11">
|
<a class="btn btn-info" href="@($"/advisor/customers/{CompanyId}/workplaces")">Arbejdssteder</a>
|
||||||
<InputTextArea id="crmNotes" class="form-control" @bind-Value="Company.CrmNotes"/>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
*@
|
||||||
<div class="row pt-3">
|
}
|
||||||
<div class="col-sm-3 d-grid">
|
|
||||||
<button type="button" class="btn btn-danger" @onclick="ToggleVisibility">@ToggleButtonText</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</EditForm>
|
</EditForm>
|
||||||
|
|
||||||
|
|
||||||
<div class="row mt-5">
|
|
||||||
<div class="col-sm-3">
|
|
||||||
<a class="btn btn-info" href="@($"/advisor/customers/{CompanyId}/workplaces")">Arbejdssteder</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (Working)
|
@if (Working)
|
||||||
|
|
|
@ -71,6 +71,7 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
||||||
private ContactModal ContactPopup { get; set; } = new();
|
private ContactModal ContactPopup { get; set; } = new();
|
||||||
private UserManagerEditView UserInfo { get; set; } = new();
|
private UserManagerEditView UserInfo { get; set; } = new();
|
||||||
private string ToggleButtonText { get; set; } = "";
|
private string ToggleButtonText { get; set; } = "";
|
||||||
|
private bool Kanvas { get; set; }
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
|
@ -96,60 +97,67 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
||||||
|
|
||||||
Company = await CustomerRepo.GetCompanyById(CompanyId);
|
Company = await CustomerRepo.GetCompanyById(CompanyId);
|
||||||
|
|
||||||
Logger.LogDebug("company => {}", JsonSerializer.Serialize(Company));
|
if (Company.Account.StartsWith("KANVAS"))
|
||||||
// toggle view button text
|
Kanvas = true;
|
||||||
ToggleButtonText = Company.IsHidden == 0 ? "Udelad kunde i oversigt" : "Brug Normal Visning";
|
|
||||||
CurrentVat = Company.VatNumber;
|
|
||||||
Company.CountryCode = UserInfo.CountryCode.ToLower();
|
|
||||||
// internal flag
|
// internal flag
|
||||||
EnableActivity = Company.ValidVat;
|
EnableActivity = Company.ValidVat;
|
||||||
// override if canvas which has account property as empty string or "NY"
|
// override if canvas which has account property as empty string or "NY"
|
||||||
if (Company.Account == "NY" || string.IsNullOrWhiteSpace(Company.Account))
|
if (Company.Account == "NY" || Company.Account.StartsWith("KANVAS") || string.IsNullOrWhiteSpace(Company.Account))
|
||||||
EnableActivity = 1;
|
EnableActivity = 1;
|
||||||
// visit interval init
|
|
||||||
if (Company.Interval == 0)
|
|
||||||
Company.Interval = 8;
|
|
||||||
// visit date init
|
|
||||||
LastVisit = DateTime.Parse(Company.LastVisit);
|
|
||||||
NextVisit = DateTime.Parse(Company.NextVisit);
|
|
||||||
// if no previous visit is registered - force last visit date to 2020
|
|
||||||
if (LastVisit.Year < 2020)
|
|
||||||
LastVisit = DateTime.Parse("2020-01-01");
|
|
||||||
// set next visit according to last visit and interval
|
|
||||||
if (!Company.ValidDateSpan())
|
|
||||||
NextVisit = LastVisit.AddDays(Company.Interval * 7);
|
|
||||||
// display urgency of next visit
|
|
||||||
VisitState = Utils.GetVisitState($"{NextVisit:yyyy-MM-dd}");
|
|
||||||
// action link passed to activity button component
|
// action link passed to activity button component
|
||||||
ActionLink = $"/advisor/customers/{CompanyId}/activities/new"; // used when drawing visit button
|
ActionLink = $"/advisor/customers/{CompanyId}/activities/new"; // used when drawing visit button
|
||||||
// handle company out of business case
|
// only execute if the company a 'real' customer
|
||||||
if (Company.HasFolded == 1)
|
if (!Kanvas)
|
||||||
{
|
{
|
||||||
// this is only used if user has selected to show closed companies
|
Logger.LogDebug("company => {}", JsonSerializer.Serialize(Company));
|
||||||
HasFolded = true;
|
// toggle view button text
|
||||||
VatState = "the-dead";
|
ToggleButtonText = Company.IsHidden == 0 ? "Udelad kunde i oversigt" : "Brug Normal Visning";
|
||||||
VisitState = "the-dead";
|
CurrentVat = Company.VatNumber;
|
||||||
|
Company.CountryCode = UserInfo.CountryCode.ToLower();
|
||||||
|
// visit interval init
|
||||||
|
if (Company.Interval == 0)
|
||||||
|
Company.Interval = 8;
|
||||||
|
// visit date init
|
||||||
|
LastVisit = DateTime.Parse(Company.LastVisit);
|
||||||
|
NextVisit = DateTime.Parse(Company.NextVisit);
|
||||||
|
// if no previous visit is registered - force last visit date to 2020
|
||||||
|
if (LastVisit.Year < 2020)
|
||||||
|
LastVisit = DateTime.Parse("2020-01-01");
|
||||||
|
// set next visit according to last visit and interval
|
||||||
|
if (!Company.ValidDateSpan())
|
||||||
|
NextVisit = LastVisit.AddDays(Company.Interval * 7);
|
||||||
|
// display urgency of next visit
|
||||||
|
VisitState = Utils.GetVisitState($"{NextVisit:yyyy-MM-dd}");
|
||||||
|
// handle company out of business case
|
||||||
|
if (Company.HasFolded == 1)
|
||||||
|
{
|
||||||
|
// this is only used if user has selected to show closed companies
|
||||||
|
HasFolded = true;
|
||||||
|
VatState = "the-dead";
|
||||||
|
VisitState = "the-dead";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// valid vat enum
|
||||||
|
Company.ValidVat = VatUtils.ValidateFormat(Company.CountryCode, Company.VatNumber) ? 1 : 0;
|
||||||
|
// valid vat flag
|
||||||
|
ValidVat = Company.ValidVat == 1; // true/false flag set if company has a valid vatNumber
|
||||||
|
// vat state css class
|
||||||
|
VatState = Company.ValidVat == 1 ? "the-good" : "no-vat"; // assign css class
|
||||||
|
}
|
||||||
|
|
||||||
|
// create search address from address
|
||||||
|
if (CountryIsDk)
|
||||||
|
CompanyVatAddress = PrepareVatAddress(Company);
|
||||||
|
|
||||||
|
await FetchContacts(CompanyId);
|
||||||
|
await Task.Delay(100);
|
||||||
|
await RequestErpUpdate();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// valid vat enum
|
|
||||||
Company.ValidVat = VatUtils.ValidateFormat(Company.CountryCode, Company.VatNumber) ? 1 : 0;
|
|
||||||
// valid vat flag
|
|
||||||
ValidVat = Company.ValidVat == 1; // true/false flag set if company has a valid vatNumber
|
|
||||||
// vat state css class
|
|
||||||
VatState = Company.ValidVat == 1 ? "the-good" : "no-vat"; // assign css class
|
|
||||||
}
|
|
||||||
|
|
||||||
// create search address from address
|
|
||||||
if (CountryIsDk)
|
|
||||||
CompanyVatAddress = PrepareVatAddress(Company);
|
|
||||||
|
|
||||||
await FetchContacts(CompanyId);
|
|
||||||
|
|
||||||
// remove loading image
|
// remove loading image
|
||||||
Working = false;
|
Working = false;
|
||||||
await Task.Delay(100);
|
|
||||||
await RequestErpUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ToggleErpEdit()
|
private void ToggleErpEdit()
|
||||||
|
@ -414,6 +422,7 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
private void HandleFieldChanged(object? sender, FieldChangedEventArgs? e)
|
private void HandleFieldChanged(object? sender, FieldChangedEventArgs? e)
|
||||||
{
|
{
|
||||||
|
|
||||||
NextVisit = LastVisit.AddDays(Company.Interval * 7);
|
NextVisit = LastVisit.AddDays(Company.Interval * 7);
|
||||||
// avoid nesting if by assuming ValidVat is false
|
// avoid nesting if by assuming ValidVat is false
|
||||||
ValidVat = false;
|
ValidVat = false;
|
||||||
|
|
|
@ -153,7 +153,7 @@ public partial class OfficeOrderCreatePage : IDisposable
|
||||||
|
|
||||||
// setting up activity properties
|
// setting up activity properties
|
||||||
Activity.ActivityStatusEnum = "noSale";
|
Activity.ActivityStatusEnum = "noSale";
|
||||||
Activity.VisitTypeEnum = "recall";
|
Activity.ActivityVisitEnum = "recall";
|
||||||
Activity.ActivityTypeEnum = "phone";
|
Activity.ActivityTypeEnum = "phone";
|
||||||
Activity.ActivityStatusEnum = "order";
|
Activity.ActivityStatusEnum = "order";
|
||||||
Activity.OurRef = $"T:{UserInfo.FirstName}";
|
Activity.OurRef = $"T:{UserInfo.FirstName}";
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
{
|
{
|
||||||
"appInfo": {
|
"appInfo": {
|
||||||
"name": "Wonky Online",
|
"name": "Wonky Online",
|
||||||
"version": "0.131.0",
|
"version": "0.132.1",
|
||||||
"rc": true,
|
"rc": true,
|
||||||
"sandBox": false,
|
"sandBox": false,
|
||||||
"image": "grumpy-coder.png"
|
"image": "grumpy-coder.png"
|
||||||
},
|
},
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Debug",
|
"Default": "Information",
|
||||||
"System": "Debug",
|
"System": "Information",
|
||||||
"Microsoft": "Information"
|
"Microsoft": "Information"
|
||||||
},
|
},
|
||||||
"Debug": {
|
"Debug": {
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"apiConfig": {
|
"apiConfig": {
|
||||||
"baseUrl": "https://dev.innotec.dk",
|
"baseUrl": "https://zeta.innotec.dk",
|
||||||
"catalog": "api/v2/catalog/country",
|
"catalog": "api/v2/catalog/country",
|
||||||
"crmCustomers": "api/v2/crm/companies",
|
"crmCustomers": "api/v2/crm/companies",
|
||||||
"crmInventoryExt": "history/inventory",
|
"crmInventoryExt": "history/inventory",
|
||||||
|
|
|
@ -24,164 +24,200 @@ public class ActivityDto
|
||||||
/// Activity entity id
|
/// Activity entity id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SalesHeadId { get; set; } = "";
|
public string SalesHeadId { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sales representative identification
|
/// Sales representative identification
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required] public string SalesRep { get; set; } = "";
|
[Required]
|
||||||
|
public string SalesRep { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sales representative entity Id
|
/// Sales representative entity Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required] public string SalesRepId { get; set; } = "";
|
[Required]
|
||||||
|
public string SalesRepId { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Company countryCode (ensure correct code when office create ordre)
|
/// Company countryCode (ensure correct code when office create ordre)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required] public string CountryCode { get; set; } = "";
|
[Required]
|
||||||
|
public string CountryCode { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Company entity Id
|
/// Company entity Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required] public string CompanyId { get; set; } = "";
|
[Required]
|
||||||
|
public string CompanyId { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Business Central entity Id
|
/// Business Central entity Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string BcId { get; set; } = "";
|
public string BcId { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer account
|
/// Customer account
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Account { get; set; } = "";
|
public string Account { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// VAT number
|
/// VAT number
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
||||||
public string VatNumber { get; set; } = "";
|
public string VatNumber { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer name
|
/// Customer name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "Navn skal udfyldes")]
|
[Required(ErrorMessage = "Navn skal udfyldes")]
|
||||||
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
||||||
public string Name { get; set; } = "";
|
public string Name { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer address city name
|
/// Customer address city name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "Byanvn skal udfyldes")]
|
[Required(ErrorMessage = "Byanvn skal udfyldes")]
|
||||||
[MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn")]
|
[MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn")]
|
||||||
public string City { get; set; }= "";
|
public string City { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer address postal code
|
/// Customer address postal code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "Postnr. skal udfyldes")]
|
[Required(ErrorMessage = "Postnr. skal udfyldes")]
|
||||||
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
||||||
public string ZipCode { get; set; } = "";
|
public string ZipCode { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer address line 1
|
/// Customer address line 1
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
||||||
public string Address1 { get; set; } = "";
|
public string Address1 { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer address line 2
|
/// Customer address line 2
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(50, ErrorMessage = "Du kan højst bruge 50 tegn")]
|
[MaxLength(50, ErrorMessage = "Du kan højst bruge 50 tegn")]
|
||||||
public string Address2 { get; set; } = "";
|
public string Address2 { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer office phone
|
/// Customer office phone
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
||||||
public string Phone { get; set; } = "";
|
public string Phone { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer mobile phone
|
/// Customer mobile phone
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
||||||
public string Mobile { get; set; } = "";
|
public string Mobile { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer office email
|
/// Customer office email
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(80, ErrorMessage = "Du kan højst bruge 80 tegn")]
|
[MaxLength(80, ErrorMessage = "Du kan højst bruge 80 tegn")]
|
||||||
public string Email { get; set; } = "";
|
public string Email { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer attention description
|
/// Customer attention description
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
||||||
public string Attention { get; set; } = "";
|
public string Attention { get; set; } = "";
|
||||||
// Form entries
|
|
||||||
/// <summary>
|
|
||||||
/// Activity type enum as string
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "Vælg aktivitetstype")]
|
|
||||||
public string ActivityTypeEnum { get; set; } = "";
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Flag express order
|
/// Flag express order
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Express { get; set; }
|
public bool Express { get; set; }
|
||||||
|
|
||||||
|
// Form entries
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Activity status enum as string
|
/// Activity status enum as string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "Vælg status for besøg ")]
|
[Required(ErrorMessage = "Vælg status for besøg ")]
|
||||||
public string ActivityStatusEnum { get; set; } = "";
|
public string ActivityStatusEnum { get; set; } = "";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Activity type enum as string
|
||||||
|
/// </summary>
|
||||||
|
[Required(ErrorMessage = "Vælg aktivitetstype")]
|
||||||
|
public string ActivityTypeEnum { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Visit type enum as string
|
/// Visit type enum as string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string VisitTypeEnum { get; set; } = "recall";
|
public string ActivityVisitEnum { get; set; } = "recall";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Activity date
|
/// Activity date
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "Dato skal angives")]
|
[Required(ErrorMessage = "Dato skal angives")]
|
||||||
public string ActivityDate { get; set; } = "";
|
public string ActivityDate { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Product demonstration
|
/// Product demonstration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(50, ErrorMessage = "Du kan højst bruge 50 tegn")]
|
[MaxLength(50, ErrorMessage = "Du kan højst bruge 50 tegn")]
|
||||||
public string Demo { get; set; } = "";
|
public string Demo { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Our reference - system generated
|
/// Our reference - system generated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
||||||
public string OurRef { get; set; } = "";
|
public string OurRef { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer reference number
|
/// Customer reference number
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
||||||
public string ReferenceNumber { get; set; } = "";
|
public string ReferenceNumber { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer reference description
|
/// Customer reference description
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(35, ErrorMessage = "Du kan højst bruge 35 tegn")]
|
[MaxLength(35, ErrorMessage = "Du kan højst bruge 35 tegn")]
|
||||||
public string YourRef { get; set; } = "";
|
public string YourRef { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processing note to office
|
/// Processing note to office
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(255, ErrorMessage = "Du kan højst bruge 255 tegn")]
|
[MaxLength(255, ErrorMessage = "Du kan højst bruge 255 tegn")]
|
||||||
public string OrderMessage { get; set; } = "";
|
public string OrderMessage { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// CRM note for future reference
|
/// CRM note for future reference
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(255, ErrorMessage = "Du kan højst bruge 255 tegn")]
|
[MaxLength(255, ErrorMessage = "Du kan højst bruge 255 tegn")]
|
||||||
public string CrmNote { get; set; } = "";
|
public string CrmNote { get; set; } = "";
|
||||||
|
|
||||||
// Delivery address form entries
|
// Delivery address form entries
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer delivery name
|
/// Customer delivery name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
||||||
public string DlvName { get; set; } = "";
|
public string DlvName { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer delivery address line 1
|
/// Customer delivery address line 1
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
|
||||||
public string DlvAddress1 { get; set; } = "";
|
public string DlvAddress1 { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer delivery address line 2
|
/// Customer delivery address line 2
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(50, ErrorMessage = "Du kan højst bruge 50 tegn")]
|
[MaxLength(50, ErrorMessage = "Du kan højst bruge 50 tegn")]
|
||||||
public string DlvAddress2 { get; set; } = "";
|
public string DlvAddress2 { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer delivery postal code
|
/// Customer delivery postal code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
[MaxLength(20, ErrorMessage = "Du kan højst bruge 20 tegn")]
|
||||||
public string DlvZipCode { get; set; } = "";
|
public string DlvZipCode { get; set; } = "";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customer delivery city name
|
/// Customer delivery city name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn")]
|
[MaxLength(30, ErrorMessage = "Du kan højst bruge 30 tegn")]
|
||||||
public string DlvCity { get; set; } = "";
|
public string DlvCity { get; set; } = "";
|
||||||
|
|
||||||
// Lines
|
// Lines
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Order lines
|
/// Order lines
|
||||||
|
|
Loading…
Reference in a new issue