cosmetic fixes found during today's lectures v.0.72.1
This commit is contained in:
parent
3a51363ea4
commit
e6b7e658b3
21 changed files with 317 additions and 235 deletions
|
@ -73,4 +73,8 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div>Ingen data</div>
|
||||
}
|
|
@ -21,23 +21,10 @@ namespace Wonky.Client.Components;
|
|||
public partial class AdvisorActivityTableComponent
|
||||
{
|
||||
[Parameter] public List<ReportItemView> Activities { get; set; }
|
||||
[Inject] public NavigationManager _navigator { get; set; }
|
||||
[Inject] public NavigationManager Navigator { get; set; }
|
||||
|
||||
// private static string GetProcessStatus(string processStatus)
|
||||
// private void ShowOrder(string companyId, string orderId)
|
||||
// {
|
||||
// return processStatus.ToLower() switch
|
||||
// {
|
||||
// "express" => "the-fast",
|
||||
// "none" => "the-good",
|
||||
// "picked" => "the-bad",
|
||||
// "packed" => "the-ugly",
|
||||
// "shipped" => "the-dead",
|
||||
// _ => ""
|
||||
// };
|
||||
// Navigator.NavigateTo($"office/customers/{companyId}/orders/{orderId}");
|
||||
// }
|
||||
|
||||
private void ShowOrder(string companyId, string orderId)
|
||||
{
|
||||
_navigator.NavigateTo($"office/customers/{companyId}/orders/{orderId}");
|
||||
}
|
||||
}
|
|
@ -18,57 +18,51 @@
|
|||
@using Wonky.Client.Components;
|
||||
@using Wonky.Client.Helpers;
|
||||
|
||||
@if (Companies.Any())
|
||||
{
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">BS</th>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">Navn</th>
|
||||
<th scope="col">Konto</th>
|
||||
<th scope="col">Tlf</th>
|
||||
<th scope="col">Bynavn</th>
|
||||
<th scope="col"></th>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">BS</th>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">Navn</th>
|
||||
<th scope="col">Konto</th>
|
||||
<th scope="col">Tlf</th>
|
||||
<th scope="col">Bynavn</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var company in Companies)
|
||||
{
|
||||
<tr @onclick="() => { ViewCustomer(company.CompanyId); }" style="cursor: pointer">
|
||||
<td class="state align-middle">
|
||||
<DisplayStateComponent StateClass="@(company.HasFolded == 1 ? "the-dead" : Utils.GetVisitState(company.NextVisit))"/>
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
@if (!string.IsNullOrWhiteSpace(company.Note))
|
||||
{
|
||||
<i class="bi-exclamation-diamond-fill text-danger" style="font-size: 2rem;"></i>
|
||||
}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
@company.Name
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
@company.Account
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
@company.Phone
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
@company.City
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<ActivityButton CompanyId="@company.CompanyId" ActionLink="/companies/$ID$/activities/new"
|
||||
ButtonText="Besøg" ButtonType="primary" Enabled="@company.ValidVat"/>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var company in Companies)
|
||||
{
|
||||
<tr @onclick="() => { ViewCustomer(company.CompanyId); }" style="cursor: pointer">
|
||||
<td class="state align-middle">
|
||||
<DisplayStateComponent StateClass="@(company.HasFolded == 1 ? "the-dead" : Utils.GetVisitState(company.NextVisit))" />
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
@if (!string.IsNullOrWhiteSpace(company.Note))
|
||||
{
|
||||
<i class="bi-exclamation-diamond-fill text-danger" style="font-size: 2rem;"></i>
|
||||
}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
@company.Name
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
@company.Account
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
@company.Phone
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
@company.City
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<ActivityButton CompanyId="@company.CompanyId" ActionLink="/companies/$ID$/activities/new"
|
||||
ButtonText="Besøg" ButtonType="primary" Enabled="@company.ValidVat" />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
else
|
||||
{
|
||||
<LoaderThreeDots />
|
||||
}
|
||||
<InformationModal BodyMessage="@_info" />
|
||||
}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<InformationModal BodyMessage="@_info"/>
|
|
@ -17,11 +17,32 @@
|
|||
|
||||
@if (Inventory.Any())
|
||||
{
|
||||
<table class="table table-striped">
|
||||
@*
|
||||
<div class="list-group">
|
||||
@foreach (var product in Inventory)
|
||||
{
|
||||
<div class="list-group-item list-group-item-action" @onclick="() => CallShowReorderModal(product.Sku)" style="cursor: pointer;">
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
@product.Description
|
||||
</div>
|
||||
<div class="col-sm-3">@product.Sku</div>
|
||||
<div class="col-sm-1">
|
||||
@product.Quantity
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<button class="btn btn-info d-block">Vis mere <i class="bi-arrow-right"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
*@
|
||||
<table class="table table-striped table-borderless">
|
||||
<tbody>
|
||||
@foreach (var product in Inventory)
|
||||
{
|
||||
<tr>
|
||||
<tr style="cursor: pointer" @onclick="() => CallShowReorderModal(product.Sku)">
|
||||
<td class="align-middle">
|
||||
@product.Description
|
||||
</td>
|
||||
|
@ -32,7 +53,7 @@
|
|||
@product.Quantity
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<a class="btn btn-dark d-block" type="button" @onclick="() => CallShowReorderModal(product.Sku)">Historik</a>
|
||||
<a class="btn btn-info d-block" type="button" @onclick="() => CallShowReorderModal(product.Sku)"><i class="bi-arrow-right-circle"></i> Se Historik</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
|
|
|
@ -14,12 +14,28 @@
|
|||
//
|
||||
|
||||
using System;
|
||||
using System.Net.Mail;
|
||||
using Wonky.Entity.DTO;
|
||||
|
||||
namespace Wonky.Client.Helpers;
|
||||
|
||||
public static class Utils
|
||||
{
|
||||
public static bool IsValidEmail(string email)
|
||||
{
|
||||
var trimmedEmail = email.Trim();
|
||||
|
||||
if (trimmedEmail.EndsWith(".")) {
|
||||
return false; // suggested by @TK-421
|
||||
}
|
||||
try {
|
||||
var addr = new MailAddress(email);
|
||||
return addr.Address == trimmedEmail;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static int GetHashFromNow()
|
||||
{
|
||||
return DateTime.Now.ToFileTimeUtc().GetHashCode();
|
||||
|
|
|
@ -86,9 +86,11 @@ public class CrmActivityHttpRepository : ICrmActivityHttpRepository
|
|||
{
|
||||
var response = await _client
|
||||
.GetAsync($"{_api.CrmActivities}/date/{activityDate}");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
return new ReportStatusView();
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
return string.IsNullOrWhiteSpace(content)
|
||||
? new ReportStatusView()
|
||||
return string.IsNullOrWhiteSpace(content)
|
||||
? new ReportStatusView()
|
||||
: JsonSerializer.Deserialize<ReportStatusView>(content, _options);
|
||||
}
|
||||
|
||||
|
@ -113,7 +115,12 @@ public class CrmActivityHttpRepository : ICrmActivityHttpRepository
|
|||
{
|
||||
var response = await _client.GetAsync($"{_api.CrmActivities}/company/{customerId}");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
return JsonSerializer.Deserialize<List<ReportItemView>>(content, _options);
|
||||
if(!response.IsSuccessStatusCode)
|
||||
return new List<ReportItemView>();
|
||||
return string.IsNullOrWhiteSpace(content)
|
||||
? new List<ReportItemView>()
|
||||
: JsonSerializer.Deserialize<List<ReportItemView>>(content, _options);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -64,7 +64,7 @@ else
|
|||
<option value="noSale">Ingen salg</option>
|
||||
@if (!string.IsNullOrEmpty(Activity.VatNumber) && !string.IsNullOrWhiteSpace(Activity.Address1) && Company.HasFolded == 0)
|
||||
{
|
||||
@if (DraftStateProvider.Draft.DraftType == "quote")
|
||||
@if (DraftStateProvider.Draft.DraftType == "order")
|
||||
{
|
||||
<option selected value="order">Bestilling</option>
|
||||
}
|
||||
|
@ -233,30 +233,25 @@ else
|
|||
<tbody>
|
||||
<tr>
|
||||
<td class="align-middle">
|
||||
<input type="number" class="form-control" @bind-value="@Quantity"/>
|
||||
<InputNumber TValue="int" class="form-control" @bind-value="@Quantity"/>
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" @bind-value="@Price"/>
|
||||
<InputNumber TValue="decimal" class="form-control" @bind-value="@Price"/>
|
||||
<button class="btn btn-warning" type="button" @onclick="CallPriceHistoryModal">
|
||||
<i class="bi-list-ul"></i>
|
||||
</button>
|
||||
@*
|
||||
<button class="btn btn-info btn-sm" type="button" @onclick="CallHistoryModal">
|
||||
<i class="oi oi-list"></i>
|
||||
</button>
|
||||
*@
|
||||
</div>
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<input type="number" class="form-control" @bind-value="@Discount"/>
|
||||
<InputNumber TValue="decimal" class="form-control" @bind-value="@Discount"/>
|
||||
</td>
|
||||
<td class="align-middle align-content-center justify-content-center">
|
||||
<input type="checkbox" class="form-check" @bind-value="@Sas"/>
|
||||
<InputCheckbox class="form-check" @bind-value="@Sas"/>
|
||||
</td>
|
||||
<td class="align-middle">@SelectedItem.Sku</td>
|
||||
<td class="align-middle">
|
||||
<button type="button" class="btn btn-warning text-nowrap d-block" @onclick="@(() => AddItem(SelectedItem))">bestil @Quantity stk @SelectedItem.Name</button>
|
||||
<button type="button" class="btn btn-primary text-nowrap d-block" @onclick="@(() => AddItem(SelectedItem))">BESTIL @SelectedItem.Name</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -334,7 +329,7 @@ else
|
|||
<a class="btn btn-warning" href="/companies/@Company.CompanyId">Tilbage</a>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<button type="button" class="btn btn-primary" @onclick="CreateActivity" disabled="@PoFormInvalid">Opret besøg</button>
|
||||
<button type="button" class="btn btn-primary" @onclick="CreateActivity" disabled="@(PoFormInvalid || Working)">Opret besøg</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ using Wonky.Client.HttpRepository;
|
|||
using Wonky.Client.Models;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
using Wonky.Client.Helpers;
|
||||
using Wonky.Client.HttpInterfaces;
|
||||
using Wonky.Client.Services;
|
||||
using Wonky.Client.Shared;
|
||||
|
@ -55,16 +56,17 @@ public partial class CrmActivityNewPage : IDisposable
|
|||
private EditContext ActivityContext { get; set; }
|
||||
private bool PoFormInvalid { get; set; } = true;
|
||||
private bool ShowItem { get; set; }
|
||||
private string Quantity = "1";
|
||||
private string Price = "0";
|
||||
private string Discount = "0";
|
||||
private bool Sas;
|
||||
private bool InvalidActivityType = true;
|
||||
private bool InvalidStatusType = true;
|
||||
private bool InvalidActivity = true;
|
||||
private bool InvalidCanvas = true;
|
||||
private bool NoHistory = true;
|
||||
private string Quantity { get; set; } = "1";
|
||||
private string Price { get; set; } = "0";
|
||||
private string Discount { get; set; } = "0";
|
||||
private bool Sas { get; set; }
|
||||
private bool InvalidActivityType { get; set; } = true;
|
||||
private bool InvalidStatusType { get; set; } = true;
|
||||
private bool InvalidActivity { get; set; } = true;
|
||||
private bool InvalidCanvas { get; set; } = true;
|
||||
private bool NoHistory { get; set; } = true;
|
||||
private bool ReportClosed { get; set; }
|
||||
private bool Working { get; set; } = true;
|
||||
private UserInfoView ThisUserInfo { get; set; } = new();
|
||||
private DateTime SelectedDate { get; set; }
|
||||
private string OldPhone { get; set; } = "";
|
||||
|
@ -75,6 +77,9 @@ public partial class CrmActivityNewPage : IDisposable
|
|||
private ProductPriceHistoryModal PriceHistoryModal { get; set; }
|
||||
private ConfirmWorkDateModal ConfirmWorkDate { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Page initialization
|
||||
/// </summary>
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
ActivityContext = new EditContext(Activity);
|
||||
|
@ -143,6 +148,7 @@ public partial class CrmActivityNewPage : IDisposable
|
|||
Activity.ActivityStatusEnum = "order";
|
||||
PoFormInvalid = false;
|
||||
}
|
||||
Working = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
@ -184,12 +190,10 @@ public partial class CrmActivityNewPage : IDisposable
|
|||
// get selected item
|
||||
if (string.IsNullOrWhiteSpace(sku.ItemId))
|
||||
return;
|
||||
|
||||
SelectedItem = await Catalog.GetSalesItemId(sku.ItemId);
|
||||
ShowItem = true;
|
||||
Price = sku.Rate;
|
||||
Quantity = sku.Quantity;
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
@ -210,7 +214,6 @@ public partial class CrmActivityNewPage : IDisposable
|
|||
{
|
||||
if (price == 0)
|
||||
return;
|
||||
|
||||
Price = price.ToString("N2", CultureInfo.InvariantCulture);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
@ -221,30 +224,33 @@ public partial class CrmActivityNewPage : IDisposable
|
|||
private async Task CreateActivity()
|
||||
{
|
||||
// disable submit button to avoid multiple clicks
|
||||
PoFormInvalid = true;
|
||||
|
||||
if (Working)
|
||||
return;
|
||||
// validate customer address1 - this is a required input
|
||||
if (string.IsNullOrWhiteSpace(Activity.Address1))
|
||||
{
|
||||
Toast.ShowError("Kunde adresse er ufuldstændig.");
|
||||
PoFormInvalid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Activity.ActivityStatusEnum == "order")
|
||||
//
|
||||
switch (Activity.ActivityStatusEnum)
|
||||
{
|
||||
if (DraftStateProvider.Draft.Items.Count == 0)
|
||||
{
|
||||
// don't accept order with no lines
|
||||
case "order" when DraftStateProvider.Draft.Items.Count == 0:
|
||||
Toast.ShowError("Ved bestilling skal der være en eller flere linjer i kladden.");
|
||||
PoFormInvalid = false;
|
||||
return;
|
||||
}
|
||||
if (Company.Account is "NY" or "" && string.IsNullOrWhiteSpace(Activity.Phone))
|
||||
{
|
||||
// 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.");
|
||||
PoFormInvalid = false;
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
// raise working flag
|
||||
Working = true;
|
||||
|
||||
// reset selected item
|
||||
SelectedItem = new SalesItemView();
|
||||
// check if phone number need to be updated
|
||||
|
@ -284,21 +290,24 @@ public partial class CrmActivityNewPage : IDisposable
|
|||
.ToList();
|
||||
Activity.Lines = lines;
|
||||
}
|
||||
// debug logging
|
||||
Logger.LogDebug("CrmNewActivityPage => \n {}", JsonSerializer.Serialize(Activity));
|
||||
// post to api
|
||||
var result = await CrmActivityRepo.CreateActivity(Activity);
|
||||
// debug logging
|
||||
Logger.LogDebug("ApiResponseView => \n {}", JsonSerializer.Serialize(result));
|
||||
// show result message
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
Toast.ShowSuccess($"{result.Message}",
|
||||
DraftStateProvider.Draft.Items.Count == 0 ? "Besøg er oprettet" : "Bestilling er oprettet");
|
||||
DraftStateProvider.Draft.Items.Count == 0 ? "Besøg er oprettet" : "Bestilling/Tilbud er oprettet");
|
||||
await DeleteDraft();
|
||||
Navigator.NavigateTo($"/companies");
|
||||
return;
|
||||
}
|
||||
|
||||
PoFormInvalid = false;
|
||||
// lower working flag
|
||||
Working = false;
|
||||
// show error message
|
||||
Toast.ShowError(result.Message, "ORDRE FEJL");
|
||||
}
|
||||
|
||||
|
@ -367,16 +376,11 @@ public partial class CrmActivityNewPage : IDisposable
|
|||
|| PoFormInvalid
|
||||
|| DraftStateProvider.Draft.Items.Count == 0
|
||||
|| (Activity.ActivityStatusEnum == "offer" && string.IsNullOrWhiteSpace(Activity.Email));
|
||||
if (Activity.YourRef.Length > 35 || Activity.ReferenceNumber.Length > 20)
|
||||
if (Activity.YourRef.Length > 35 || Activity.ReferenceNumber.Length > 20 || InvalidActivity)
|
||||
{
|
||||
PoFormInvalid = true;
|
||||
return;
|
||||
}
|
||||
if (InvalidActivity)
|
||||
{
|
||||
PoFormInvalid = true;
|
||||
return;
|
||||
}
|
||||
PoFormInvalid = !ActivityContext.Validate();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
|
|
@ -20,68 +20,80 @@
|
|||
@page "/companies/{CompanyId}/activities"
|
||||
@attribute [Authorize(Roles = "Advisor")]
|
||||
|
||||
|
||||
<h2>@Company.Name</h2>
|
||||
|
||||
<div class="list-group">
|
||||
<div class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h4>Dato</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Demo</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Salg</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Note /Kontor</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Note /Selv</h4>
|
||||
</div>
|
||||
@if (!string.IsNullOrWhiteSpace(Company.Name))
|
||||
{
|
||||
<div class="row pt-2 pb-1 rounded-2 bg-dark text-white">
|
||||
<div class="col-sm-6">
|
||||
<h4 class="pt-1">@Company.Name</h4>
|
||||
</div>
|
||||
<div class="col-sm-3 align-content-end">
|
||||
<a class="btn btn-primary d-block" href="/companies/@Company.CompanyId"><i class="bi-arrow-right"></i> Kundekort</a>
|
||||
</div>
|
||||
<div class="col-sm-3 align-content-end">
|
||||
<a class="btn btn-primary d-block" href="/companies/@Company.CompanyId/activities/new"><i class="bi-arrow-right"></i> Besøg</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-group">
|
||||
<div class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h4>Dato</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Demo</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Salg</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Note /Kontor</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Note /Selv</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (Activities.Any())
|
||||
{
|
||||
@foreach (var activity in Activities)
|
||||
@if (Activities.Any())
|
||||
{
|
||||
@foreach (var activity in Activities)
|
||||
{
|
||||
<div class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@activity.OrderDate
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.Demo
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.Sales
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.OfficeNote
|
||||
</div>
|
||||
<div class="col">
|
||||
ikke fuldt implementeret
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@activity.OrderDate
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.Demo
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.Sales
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.OfficeNote
|
||||
</div>
|
||||
<div class="col">
|
||||
|
||||
Ingen data
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
<div class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
Ingen data
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Working)
|
||||
{
|
||||
<LoaderThreeDots />
|
||||
}
|
||||
<LoaderThreeDots/>
|
||||
}
|
|
@ -28,7 +28,6 @@ namespace Wonky.Client.Pages;
|
|||
public partial class CrmCompanyActivityListPage : IDisposable
|
||||
{
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
|
||||
[Inject] public HttpInterceptorService _interceptor { get; set; }
|
||||
[Inject] public ICrmActivityHttpRepository CrmActivityRepo { get; set; }
|
||||
[Inject] public ICrmCompanyHttpRepository CompanyRepo { get; set; }
|
||||
|
@ -42,12 +41,19 @@ public partial class CrmCompanyActivityListPage : IDisposable
|
|||
_interceptor.RegisterBeforeSendEvent();
|
||||
|
||||
Company = await CompanyRepo.GetCompanyById(CompanyId);
|
||||
|
||||
Activities = await CrmActivityRepo.GetCustomerActivities(CompanyId);
|
||||
Activities = Activities.OrderByDescending(x => x.OrderDate).ToList();
|
||||
await GetActivities();
|
||||
Working = false;
|
||||
}
|
||||
|
||||
private async Task GetActivities()
|
||||
{
|
||||
Working = true;
|
||||
Activities = await CrmActivityRepo.GetCustomerActivities(CompanyId);
|
||||
if(Activities.Any())
|
||||
Activities = Activities.OrderByDescending(x => x.OrderDate).ToList();
|
||||
Working = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_interceptor.DisposeEvent();
|
||||
|
|
|
@ -19,13 +19,15 @@
|
|||
@using Microsoft.AspNetCore.Authorization
|
||||
@page "/companies/{CompanyId}/h/i"
|
||||
@attribute [Authorize(Roles = "Advisor")]
|
||||
<div class="row pt-2 pb-2 rounded-2 bg-dark text-white">
|
||||
<div class="col-6">
|
||||
<h3>@Company.Name</h3>
|
||||
<div class="row pt-2 pb-1 rounded-2 bg-dark text-white">
|
||||
<div class="col-sm-6">
|
||||
<h4 class="pt-1">@Company.Name</h4>
|
||||
</div>
|
||||
<div class="col-6 align-content-end">
|
||||
<a class="btn btn-primary" href="/companies/@Company.CompanyId">Kundekort</a>
|
||||
<a class="btn btn-primary" href="/companies/@Company.CompanyId/activities/new">Besøg</a>
|
||||
<div class="col-sm-3 align-content-end">
|
||||
<a class="btn btn-primary d-block" href="/companies/@Company.CompanyId"><i class="bi-arrow-right"></i> Kundekort</a>
|
||||
</div>
|
||||
<div class="col-sm-3 align-content-end">
|
||||
<a class="btn btn-primary d-block" href="/companies/@Company.CompanyId/activities/new"><i class="bi-arrow-right"></i> Besøg</a>
|
||||
</div>
|
||||
</div>
|
||||
@if (Loading)
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
@using Wonky.Client.Components
|
||||
@if (!string.IsNullOrWhiteSpace(Company.Name))
|
||||
{
|
||||
<div class="row pt-2 pb-2 rounded-2 bg-dark text-white">
|
||||
<div class="col-6">
|
||||
<h3>@Company.Name</h3>
|
||||
<div class="row pt-2 pb-1 rounded-2 bg-dark text-white">
|
||||
<div class="col-sm-6">
|
||||
<h4 class="pt-1">@Company.Name</h4>
|
||||
</div>
|
||||
<div class="col-6 align-content-end">
|
||||
<a class="btn btn-primary" href="/companies/@Company.CompanyId">Kundekort</a>
|
||||
<a class="btn btn-primary" href="/companies/@Company.CompanyId/activities/new">Besøg</a>
|
||||
<div class="col-sm-3 align-content-end">
|
||||
<a class="btn btn-primary d-block" href="/companies/@Company.CompanyId"><i class="bi-arrow-right"></i> Kundekort</a>
|
||||
</div>
|
||||
<div class="col-sm-3 align-content-end">
|
||||
<a class="btn btn-primary d-block" href="/companies/@Company.CompanyId/activities/new"><i class="bi-arrow-right"></i> Besøg</a>
|
||||
</div>
|
||||
</div>
|
||||
<InvoiceTableComponent CompanyId="@CompanyId" InvoiceList="@History.Invoices"/>
|
||||
|
|
|
@ -54,4 +54,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<AdvisorCompanyTableComponent Companies="_companyList" OnDelete="DeleteCompany" />
|
||||
<AdvisorCompanyTableComponent Companies="_companyList" OnDelete="DeleteCompany" />
|
||||
@if (Working)
|
||||
{
|
||||
<LoaderThreeDots />
|
||||
}
|
|
@ -42,6 +42,7 @@ namespace Wonky.Client.Pages
|
|||
private UserInfoView _userInfo { get; set; } = new();
|
||||
private string _savedSearch { get; set; } = "";
|
||||
private bool _includeFolded { get; set; }
|
||||
private bool Working { get; set; } = true;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
|
@ -132,9 +133,11 @@ namespace Wonky.Client.Pages
|
|||
|
||||
private async Task GetCompanies()
|
||||
{
|
||||
Working = true;
|
||||
var pagingResponse = await _companyRepo.GetCompanies(_paging);
|
||||
_companyList = pagingResponse.Items;
|
||||
_metaData = pagingResponse.MetaData;
|
||||
Working = false;
|
||||
}
|
||||
|
||||
public void Dispose() => _interceptor.DisposeEvent();
|
||||
|
|
|
@ -123,7 +123,7 @@
|
|||
</div>
|
||||
@* save vat number *@
|
||||
<div class="col-sm-2 text-end">
|
||||
<button type="button" class="btn btn-primary" @onclick="UpdateVatNumber">MOMS Nr<i class="bi-save"></i></button>
|
||||
<button type="button" class="btn btn-primary" @onclick="UpdateVatNumber">MOMS Nr. <i class="bi-save"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -131,16 +131,16 @@
|
|||
@* activity buttons *@
|
||||
<div class="row mt-3 mb-2">
|
||||
<div class="col">
|
||||
<a class="btn btn-light border-dark d-block" href="/companies/@Company.CompanyId/invoices">Poster</a>
|
||||
<a class="btn btn-dark opacity-50 d-block" href="/companies/@Company.CompanyId/invoices">Poster</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a class="btn btn-light border-dark d-block" href="/companies/@Company.CompanyId/quotes">Tilbud</a>
|
||||
<a class="btn btn-dark opacity-50 d-block" href="/companies/@Company.CompanyId/quotes">Tilbud</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a class="btn btn-light border-dark d-block" href="/companies/@Company.CompanyId/activities">Besøg</a>
|
||||
<a class="btn btn-dark opacity-50 d-block" href="/companies/@Company.CompanyId/activities">Besøg</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a class="btn btn-light border-dark d-block" href="/companies/@Company.CompanyId/h/i">Produkter</a>
|
||||
<a class="btn btn-dark opacity-50 d-block" href="/companies/@Company.CompanyId/h/i">Produkter</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<ActivityButton ActionLink="@ActionLink"
|
||||
|
@ -168,7 +168,7 @@
|
|||
</div>
|
||||
@* Save CRM data button *@
|
||||
<div class="col-sm-3 text-end">
|
||||
<button type="button" class="btn btn-primary" @onclick="UpdateCrmData">CRM <i class="bi-save"></i></button>
|
||||
<button type="button" class="btn btn-primary" @onclick="UpdateCrmData">CRM data <i class="bi-save"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
@* crm context - contacts *@
|
||||
|
@ -232,10 +232,6 @@
|
|||
</div>
|
||||
</EditForm>
|
||||
}
|
||||
else
|
||||
{
|
||||
<LoaderThreeDots/>
|
||||
}
|
||||
|
||||
<VatLookupDkModal VatAddress="CompanyVatAddress" EntityName="@Company.Name" VatNumber="@Company.VatNumber"
|
||||
@ref="VatLookupPopup" OnSelectedCompany="SelectedCompanyCallback" />
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
@* report header *@
|
||||
<div class="row sticky-top bg-dark text-white rounded-2 mb-2 py-2 align-items-center">
|
||||
<div class="col-sm-8">
|
||||
<WorkDateComponent OnChangedCallback="SetWorkDate"/>
|
||||
<WorkDateComponent OnChangedCallback="SetWorkDateCallback"/>
|
||||
</div>
|
||||
<div class="col-sm-4 text-end">
|
||||
<AdvisorActivityKmStartComponent/>
|
||||
|
@ -45,14 +45,14 @@
|
|||
<th scope="col">Dag / Periode</th>
|
||||
<th scope="col">Begyndt</th>
|
||||
<th scope="col">Afsluttet</th>
|
||||
@* <th></th> *@
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<select id="dayType" class="col-md-3 form-select text-bg-primary bg-primary"
|
||||
<InputSelect id="dayType" class="form-select text-bg-primary bg-primary"
|
||||
@bind-Value="Report.DayTypeEnum" @bind-Value:event="onchange">
|
||||
<option value="">→ TAG MIG ←</option>
|
||||
<option value="sales">Salgsdag</option>
|
||||
|
@ -61,7 +61,7 @@
|
|||
<option value="supervisor">Medkørende Supervisor</option>
|
||||
<option value="sickLeave">Sygdom</option>
|
||||
<option value="leave">Ferie</option>
|
||||
</select>
|
||||
</InputSelect>
|
||||
<ValidationMessage For="@(() => Report.DayTypeEnum)"/>
|
||||
</td>
|
||||
@if (Report.DayTypeEnum.ToLower().Contains("leave"))
|
||||
|
@ -72,9 +72,11 @@
|
|||
<td>
|
||||
<InputDate class="form-control" @bind-Value="EndLeave"/>
|
||||
</td>
|
||||
Report.Figures.KmMorning = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Report.Figures.KmMorning = Preferences.KmMorning;
|
||||
<td>
|
||||
<input type="time" id="checkIn" class="form-control"
|
||||
@bind-Value="_checkIn" @bind-Value:event="oninput" @onchange="OnTimeChanged"/>
|
||||
|
@ -84,21 +86,17 @@
|
|||
@bind-Value="_checkOut" @bind-Value:event="oninput" @onchange="OnTimeChanged"/>
|
||||
</td>
|
||||
}
|
||||
@*
|
||||
<th>
|
||||
<td class="text-end">
|
||||
<button type="button" class="btn btn-warning"
|
||||
@onclick="GetKeyFigures" disabled="@(!NoFigures)">
|
||||
Nøgletal
|
||||
</button>
|
||||
</th>
|
||||
*@
|
||||
</td>
|
||||
<td class="text-end">
|
||||
@* <div style="display:@(_working ? "none" : "block");"> *@
|
||||
<button type="button" class="btn btn-primary"
|
||||
@onclick="SubmitReport" disabled="@(NoFigures || Working)">
|
||||
Gem Rapport
|
||||
</button>
|
||||
@* </div> *@
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -114,7 +112,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th scope="col" style="width:60%">Tekst</th>
|
||||
<th scope="col">Medkørende Supervisor</th>
|
||||
<th scope="col">Supervisor</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -126,7 +124,6 @@
|
|||
<td>
|
||||
<InputText id="supervisedBy" class="form-control" @bind-Value="Report.SupervisedBy"/>
|
||||
<ValidationMessage For="@(() => Report.SupervisedBy)"/>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -304,5 +301,5 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</EditForm>>
|
||||
<ConfirmationModal BodyMessage="@Prompt" OnOkClicked="ReportSaveConfirmed" @ref="ConfirmReportModal"/>
|
||||
</EditForm>
|
||||
<ConfirmationModal BodyMessage="@Prompt" OnOkClicked="ConfirmSaveCallback" @ref="ConfirmReportModal"/>
|
|
@ -46,9 +46,9 @@ public partial class CrmReportNewPage : IDisposable
|
|||
private List<ReportItemView> Activities { get; set; } = new();
|
||||
private ReportFiguresDto InitialValues { get; set; }
|
||||
private Preferences Preferences { get; set; } = new();
|
||||
private bool FormInvalid = true;
|
||||
private bool NoFigures = true;
|
||||
private bool Working;
|
||||
private bool FormInvalid { get; set; } = true;
|
||||
private bool NoFigures { get; set; } = true;
|
||||
private bool Working { get; set; } = true;
|
||||
private DateTime _workDate { get; set; } = DateTime.Now;
|
||||
private TimeOnly _checkIn { get; set; } = new(12, 0);
|
||||
private TimeOnly _checkOut { get; set; } = new(12, 0);
|
||||
|
@ -57,6 +57,9 @@ public partial class CrmReportNewPage : IDisposable
|
|||
private ConfirmationModal ConfirmReportModal { get; set; }
|
||||
private string Prompt { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// OnInitialized
|
||||
/// </summary>
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Interceptor.RegisterEvent();
|
||||
|
@ -81,8 +84,14 @@ public partial class CrmReportNewPage : IDisposable
|
|||
Report.Figures.Distance = 0;
|
||||
Report.Figures.DistancePrivateMonth = 0;
|
||||
await GetKeyFigures();
|
||||
Working = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Field data change event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
||||
{
|
||||
Console.WriteLine($"e Model => {e.FieldIdentifier.Model}");
|
||||
|
@ -91,6 +100,11 @@ public partial class CrmReportNewPage : IDisposable
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation change event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
||||
{
|
||||
FormInvalid = false;
|
||||
|
@ -100,7 +114,10 @@ public partial class CrmReportNewPage : IDisposable
|
|||
ReportContext.OnValidationStateChanged += ValidationChanged;
|
||||
}
|
||||
|
||||
private async Task ReportSaveConfirmed()
|
||||
/// <summary>
|
||||
/// Save report confirmed callback
|
||||
/// </summary>
|
||||
private async Task ConfirmSaveCallback()
|
||||
{
|
||||
// attempt to eliminate doubled click on submit button
|
||||
if (Working)
|
||||
|
@ -114,27 +131,30 @@ public partial class CrmReportNewPage : IDisposable
|
|||
await PreferenceService.SetDateConfirmed(false);
|
||||
Navigator.NavigateTo($"/sales-reports/view/{_workDate:yyyy-MM-dd}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Submit report
|
||||
/// </summary>
|
||||
private void SubmitReport()
|
||||
{
|
||||
// attempt to eliminate doubled click on submit button
|
||||
if (Working)
|
||||
return;
|
||||
|
||||
// check daytype
|
||||
if (string.IsNullOrWhiteSpace(Report.DayTypeEnum))
|
||||
{
|
||||
Toaster.ShowError("Dagtype skal vælges", "Dag type skal angives");
|
||||
Toaster.ShowError("Dagtype skal vælges", "Dag type mangler");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Report.Figures.KmMorning > Report.Figures.KmEvening)
|
||||
// distance day check - only if not leave
|
||||
if (Report.Figures.KmMorning > Report.Figures.KmEvening && !Report.DayTypeEnum.ToLower().Contains("leave"))
|
||||
{
|
||||
Toaster.ShowError("Km udregning er negativ - kontroller venligst km tal", "Kontroller km tal");
|
||||
return;
|
||||
}
|
||||
|
||||
// local working variables
|
||||
DateTime checkIn;
|
||||
DateTime checkOut;
|
||||
// create a date time object using workDate and workHour input
|
||||
if (Report.DayTypeEnum.ToLower().Contains("leave"))
|
||||
{
|
||||
checkIn = new DateTime(BeginLeave.Year, BeginLeave.Month, BeginLeave.Day, 0, 0, 0);
|
||||
|
@ -145,23 +165,27 @@ public partial class CrmReportNewPage : IDisposable
|
|||
checkIn = new DateTime(_workDate.Year, _workDate.Month, _workDate.Day, _checkIn.Hour, _checkIn.Minute, 0);
|
||||
checkOut = new DateTime(_workDate.Year, _workDate.Month, _workDate.Day, _checkOut.Hour, _checkOut.Minute, 0);
|
||||
}
|
||||
|
||||
// assign a workday number if the day is marked as salesDay
|
||||
Report.SalesDayNumber = Report.DayTypeEnum == "sales" ? Report.Figures.SalesDayCount + 1 : 0;
|
||||
// format report date time input
|
||||
Report.FromDateTime = checkIn.ToString("yyyy-MM-dd'T'HH:mm:ss", CultureInfo.InvariantCulture);
|
||||
Report.ToDateTime = checkOut.ToString("yyyy-MM-dd'T'HH:mm:ss", CultureInfo.InvariantCulture);
|
||||
|
||||
// assign final distance numbers
|
||||
Report.Figures.Distance = Report.Figures.KmEvening - Report.Figures.KmMorning;
|
||||
Report.Figures.DistanceMonth += Report.Figures.Distance;
|
||||
Report.Figures.DistancePrivateMonth += Report.Figures.DistancePrivate;
|
||||
|
||||
Logger.LogDebug("_workDate => {workDate}", $"{_workDate:yyyy-MM-dd}");
|
||||
Logger.LogDebug("_report => {report}", JsonSerializer.Serialize(Report));
|
||||
|
||||
// create a prompt
|
||||
Prompt = Report.Figures.Distance > 1000 ? $"'{Report.Figures.Distance}'KM tal er meget højt. Er du sikker på at det er rigtigt? Gem rapport for {_workDate.ToLongDateString()}?" : $"Gem Rapport for {_workDate.ToLongDateString()}?";
|
||||
|
||||
// pop confirmation
|
||||
ConfirmReportModal.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On Time changed - update the Report Date fields
|
||||
/// </summary>
|
||||
private void OnTimeChanged()
|
||||
{
|
||||
var f = new DateTime(_workDate.Year, _workDate.Month, _workDate.Day, _checkIn.Hour, _checkIn.Minute,0);
|
||||
|
@ -170,8 +194,12 @@ public partial class CrmReportNewPage : IDisposable
|
|||
var t = new DateTime(_workDate.Year, _workDate.Month, _workDate.Day, _checkOut.Hour, _checkOut.Minute,0);
|
||||
Report.ToDateTime = $"{t:yyyy-MM-dd'T'HH:mm}";
|
||||
}
|
||||
|
||||
private void SetWorkDate(string workDate)
|
||||
|
||||
/// <summary>
|
||||
/// Set workDate callback
|
||||
/// </summary>
|
||||
/// <param name="workDate"></param>
|
||||
private void SetWorkDateCallback(string workDate)
|
||||
{
|
||||
_workDate = DateTime.Parse(workDate);
|
||||
NoFigures = true;
|
||||
|
@ -187,7 +215,10 @@ public partial class CrmReportNewPage : IDisposable
|
|||
Report.FromDateTime = $"{_workDate:yyyy-MM-dd'T'12:00}";
|
||||
Report.ToDateTime = $"{_workDate:yyyy-MM-dd'T'12:00}";
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get key figures from backend
|
||||
/// </summary>
|
||||
private async Task GetKeyFigures()
|
||||
{
|
||||
Working = true;
|
||||
|
@ -197,7 +228,8 @@ public partial class CrmReportNewPage : IDisposable
|
|||
Report.Figures = data.ReportData;
|
||||
InitialValues = data.ReportData;
|
||||
Activities = data.ReportItems;
|
||||
Report.Figures.KmMorning = Preferences.KmMorning;
|
||||
if(!Report.DayTypeEnum.ToLower().Contains("leave"))
|
||||
Report.Figures.KmMorning = Preferences.KmMorning;
|
||||
NoFigures = false;
|
||||
Working = false;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*@
|
||||
|
||||
<div class="modal" tabindex="-1" role="dialog" style="display:@_modalDisplay">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">Bekræft Venligst</h3>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*@
|
||||
|
||||
<div class="modal" tabindex="-1" role="dialog" style="display:@_modalDisplay">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Bekræft Venligst</h5>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
@* <div class="modal" tabindex="-1" role="dialog" style="display:@_modalDisplay"> *@
|
||||
<div class="modal fade" tabindex="-1" style="display:@_modalDisplay">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-info">
|
||||
<h5 class="modal-title">Info</h5>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"appInfo": {
|
||||
"name": "Wonky Client",
|
||||
"version": "0.71.1",
|
||||
"version": "0.72.1",
|
||||
"rc": true,
|
||||
"sandBox": false,
|
||||
"image": "grumpy-coder.png"
|
||||
|
|
Loading…
Reference in a new issue