RC build v161.0
FEAT more info stored in localStorage - TODO check browser storage limit
This commit is contained in:
parent
c523e9a475
commit
3c738e3313
43 changed files with 1242 additions and 723 deletions
|
@ -13,6 +13,7 @@
|
|||
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||
//
|
||||
|
||||
using System.Reflection.Metadata;
|
||||
using System.Text.Json;
|
||||
using Blazored.LocalStorage;
|
||||
using Blazored.Toast.Services;
|
||||
|
@ -22,30 +23,45 @@ using Microsoft.VisualBasic;
|
|||
using Wonky.Client.HttpInterceptors;
|
||||
using Wonky.Client.HttpRepository;
|
||||
using Wonky.Client.Local.Services;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Client.Shared;
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Models;
|
||||
using Wonky.Entity.Views;
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace Wonky.Client.Components;
|
||||
public partial class AdvisorLandingComponent
|
||||
{
|
||||
// ##############################################################
|
||||
[Inject] public UserPreferenceService PreferenceService { get; set; }
|
||||
[Inject] public IDrawerCabinetService DrawerCabinetService { get; set; }
|
||||
[Inject] public IUserInfoService UserInfo { get; set; }
|
||||
[Inject] public ICountryCatalogRepository CatalogRepo { get; set; }
|
||||
|
||||
private readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions
|
||||
|
||||
// ##############################################################
|
||||
private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
};
|
||||
|
||||
private UserPreference Profiles { get; set; } = new();
|
||||
private DateTime SelectedDate { get; set; }
|
||||
// private DateTime SelectedDate { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Profiles = await PreferenceService.GetProfile();
|
||||
SelectedDate = string.IsNullOrWhiteSpace(Profiles.WorkDate) ? DateTime.Now : DateTime.Parse(Profiles.WorkDate);
|
||||
|
||||
// SelectedDate = string.IsNullOrWhiteSpace(Profiles.WorkDate) ? DateTime.Parse(Profiles.WorkDate) : DateTime.Today;
|
||||
}
|
||||
|
||||
// protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
// {
|
||||
// if (firstRender)
|
||||
// {
|
||||
// var countryCode = await UserInfo.GetCountryCode();
|
||||
// var _ = await DrawerCabinetService.GetCatalogDrawer(countryCode);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
@using Wonky.Entity.Views
|
||||
@using System.Linq.Expressions
|
||||
|
||||
@if (InvoiceList.Any())
|
||||
@if (Invoices.Any())
|
||||
{
|
||||
<div class="list-group">
|
||||
<div class="list-group-item">
|
||||
|
@ -37,7 +37,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@foreach (var invoice in InvoiceList)
|
||||
@foreach (var invoice in Invoices)
|
||||
{
|
||||
<div class="list-group-item list-group-item-action" @onclick="@(() => ShowInvoice(invoice.ArchiveHeadId))">
|
||||
<div class="row">
|
||||
|
|
|
@ -20,10 +20,17 @@ namespace Wonky.Client.Components;
|
|||
|
||||
public partial class CustomerInvoiceListComponent
|
||||
{
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
[Parameter] public List<InvoiceListItemView> InvoiceList { get; set; } = new();
|
||||
[Parameter] public List<InvoiceListItemView> Invoices { get; set; } = new();
|
||||
[Parameter] public EventCallback<string> OnShowInvoice { get; set; }
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (Invoices.Any())
|
||||
{
|
||||
Invoices = Invoices.OrderByDescending(x => x.DocumentDate).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ShowInvoice(string invoiceId)
|
||||
{
|
||||
await OnShowInvoice.InvokeAsync(invoiceId);
|
||||
|
|
|
@ -50,7 +50,7 @@ public class CrmContactRepository : ICrmContactRepository
|
|||
/// </summary>
|
||||
/// <param name="contact"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> CreateContact(ContactDto contact)
|
||||
public async Task<string> PostContact(ContactDto contact)
|
||||
{
|
||||
var response = await _client.PostAsJsonAsync(
|
||||
$"{_conf.CrmCustomers}/{contact.CompanyId}/contacts", contact, _options);
|
||||
|
@ -100,7 +100,7 @@ public class CrmContactRepository : ICrmContactRepository
|
|||
/// </summary>
|
||||
/// <param name="contact"></param>
|
||||
/// <returns></returns>
|
||||
public async Task UpdateContact(ContactDto contact)
|
||||
public async Task PutContact(ContactDto contact)
|
||||
{
|
||||
await _client.PutAsJsonAsync(
|
||||
$"{_conf.CrmCustomers}/{contact.CompanyId}/contacts/{contact.ContactId}", contact, _options);
|
||||
|
|
|
@ -46,7 +46,19 @@ public class CrmCustomerHistoryRepository : ICrmCustomerHistoryRepository
|
|||
}
|
||||
|
||||
|
||||
public async Task<InvoiceListView> FetchInvoiceList(string companyId)
|
||||
public async Task<List<InvoiceListItemView>> GetInvoiceList(string companyId)
|
||||
{
|
||||
var response = await _client.GetAsync($"{_api.CrmCustomers}/{companyId}/invoices/list");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
if (!response.IsSuccessStatusCode || string.IsNullOrWhiteSpace(content))
|
||||
{
|
||||
return new List<InvoiceListItemView>();
|
||||
}
|
||||
return JsonSerializer.Deserialize<List<InvoiceListItemView>>(content, _options) ?? new List<InvoiceListItemView>();
|
||||
}
|
||||
|
||||
|
||||
public async Task<InvoiceListView> GetInvoiceListHeader(string companyId)
|
||||
{
|
||||
var response = await _client.GetAsync($"{_api.CrmCustomers}/{companyId}/invoices");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
@ -58,7 +70,7 @@ public class CrmCustomerHistoryRepository : ICrmCustomerHistoryRepository
|
|||
}
|
||||
|
||||
|
||||
public async Task<InvoiceView> FetchInvoice(string companyId, string invoiceId)
|
||||
public async Task<InvoiceView> GetInvoice(string companyId, string invoiceId)
|
||||
{
|
||||
var content = await _client
|
||||
.GetFromJsonAsync<InvoiceView>($"{_api.CrmCustomers}/{companyId}/invoices/{invoiceId}", _options);
|
||||
|
@ -66,7 +78,7 @@ public class CrmCustomerHistoryRepository : ICrmCustomerHistoryRepository
|
|||
}
|
||||
|
||||
|
||||
public async Task<List<ProductInventoryItemView>> FetchInventory(string companyId)
|
||||
public async Task<List<ProductInventoryItemView>> GetInventory(string companyId)
|
||||
{
|
||||
var response = await _client.GetAsync($"{_api.CrmCustomers}/{companyId}/{_api.CrmInventoryExt}");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
@ -112,7 +124,7 @@ public class CrmCustomerHistoryRepository : ICrmCustomerHistoryRepository
|
|||
}
|
||||
|
||||
|
||||
public async Task<string> GetRecycledInvoiceList(string companyId, string syncDate, bool force)
|
||||
public async Task<string> RequestErpSync(string companyId, string syncDate, bool force)
|
||||
{
|
||||
var x = await _client.GetAsync($"{_api.SyncInvoice}/{companyId}/{syncDate}?force={force}");
|
||||
var content = await x.Content.ReadAsStringAsync();
|
||||
|
|
|
@ -28,7 +28,7 @@ public interface ICrmContactRepository
|
|||
/// </summary>
|
||||
/// <param name="contact"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> CreateContact(ContactDto contact);
|
||||
Task<string> PostContact(ContactDto contact);
|
||||
|
||||
/// <summary>
|
||||
/// Get Contact
|
||||
|
@ -58,5 +58,5 @@ public interface ICrmContactRepository
|
|||
/// </summary>
|
||||
/// <param name="contact"></param>
|
||||
/// <returns></returns>
|
||||
Task UpdateContact(ContactDto contact);
|
||||
Task PutContact(ContactDto contact);
|
||||
}
|
|
@ -22,12 +22,19 @@ namespace Wonky.Client.HttpRepository;
|
|||
/// </summary>
|
||||
public interface ICrmCustomerHistoryRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Return invoice list without company information
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<InvoiceListItemView>> GetInvoiceList(string companyId);
|
||||
|
||||
/// <summary>
|
||||
/// Fetch Invoice LIst
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <returns></returns>
|
||||
Task<InvoiceListView> FetchInvoiceList(string companyId);
|
||||
Task<InvoiceListView> GetInvoiceListHeader(string companyId);
|
||||
|
||||
/// <summary>
|
||||
/// Fetch given invoice for given customer
|
||||
|
@ -35,14 +42,14 @@ public interface ICrmCustomerHistoryRepository
|
|||
/// <param name="companyId"></param>
|
||||
/// <param name="invoiceId"></param>
|
||||
/// <returns></returns>
|
||||
Task<InvoiceView> FetchInvoice(string companyId, string invoiceId);
|
||||
Task<InvoiceView> GetInvoice(string companyId, string invoiceId);
|
||||
|
||||
/// <summary>
|
||||
/// Fetch inventory from given customer
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<ProductInventoryItemView>> FetchInventory(string companyId);
|
||||
Task<List<ProductInventoryItemView>> GetInventory(string companyId);
|
||||
|
||||
/// <summary>
|
||||
/// Fetch History for given customer
|
||||
|
@ -74,5 +81,5 @@ public interface ICrmCustomerHistoryRepository
|
|||
/// <param name="syncDate"></param>
|
||||
/// <param name="force"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> GetRecycledInvoiceList(string companyId, string syncDate, bool force);
|
||||
Task<string> RequestErpSync(string companyId, string syncDate, bool force);
|
||||
}
|
291
Wonky.Client/Local.Services/DrawerCabinetService.cs
Normal file
291
Wonky.Client/Local.Services/DrawerCabinetService.cs
Normal file
|
@ -0,0 +1,291 @@
|
|||
using System.Text.Json;
|
||||
using Blazored.LocalStorage;
|
||||
using Wonky.Client.HttpRepository;
|
||||
using Wonky.Client.Models;
|
||||
|
||||
namespace Wonky.Client.Local.Services;
|
||||
|
||||
public class DrawerCabinetService : IDrawerCabinetService
|
||||
{
|
||||
private readonly JsonSerializerOptions _options = new ()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
private readonly ILogger<DrawerCabinetService> _logger;
|
||||
private readonly ILocalStorageService _asyncStorageService;
|
||||
private readonly ISyncLocalStorageService _syncStorageService;
|
||||
private readonly ICrmActivityRepository _activityRepo;
|
||||
private readonly ICrmCustomerRepository _customerRepo;
|
||||
private readonly ICrmCustomerHistoryRepository _historyRepo;
|
||||
private readonly ICountryCatalogRepository _catalogRepo;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="asyncStorageService"></param>
|
||||
/// <param name="syncStorageService"></param>
|
||||
/// <param name="catalogRepo"></param>
|
||||
/// <param name="historyRepo"></param>
|
||||
/// <param name="customerRepo"></param>
|
||||
/// <param name="activityRepo"></param>
|
||||
public DrawerCabinetService(
|
||||
ILogger<DrawerCabinetService> logger,
|
||||
ILocalStorageService asyncStorageService,
|
||||
ISyncLocalStorageService syncStorageService,
|
||||
ICountryCatalogRepository catalogRepo,
|
||||
ICrmCustomerHistoryRepository historyRepo,
|
||||
ICrmCustomerRepository customerRepo,
|
||||
ICrmActivityRepository activityRepo)
|
||||
{
|
||||
_logger = logger;
|
||||
_asyncStorageService = asyncStorageService;
|
||||
_syncStorageService = syncStorageService;
|
||||
_catalogRepo = catalogRepo;
|
||||
_historyRepo = historyRepo;
|
||||
_customerRepo = customerRepo;
|
||||
_activityRepo = activityRepo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Activity
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <param name="force"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ActivityDrawer> GetActivityDrawerAsync(string companyId, bool force = false)
|
||||
{
|
||||
var drawer = await _asyncStorageService
|
||||
.GetItemAsync<ActivityDrawer>($"{companyId}.{ActivityDrawer.Label}");
|
||||
if (drawer == null) force = true;
|
||||
if (force)
|
||||
{
|
||||
var result = await _activityRepo.GetCustomerActivities(companyId);
|
||||
drawer = new ActivityDrawer
|
||||
{
|
||||
LastDateModified = DateTime.Today,
|
||||
Content = result
|
||||
};
|
||||
await StoreActivityDrawerAsync(companyId, drawer);
|
||||
}
|
||||
_logger.LogDebug("ActivityDrawer {}", JsonSerializer.Serialize(drawer, _options));
|
||||
return drawer ?? new ActivityDrawer();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sales Catalog
|
||||
/// </summary>
|
||||
/// <param name="countryCode"></param>
|
||||
/// <param name="force"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<CatalogDrawer> GetCatalogDrawerAsync(string countryCode, bool force = false)
|
||||
{
|
||||
var drawer = await _asyncStorageService
|
||||
.GetItemAsync<CatalogDrawer>($"{countryCode}.{CatalogDrawer.Label}");
|
||||
|
||||
if (drawer == null) force = true;
|
||||
if (force)
|
||||
{
|
||||
var result = await _catalogRepo.GetPriceList(countryCode);
|
||||
drawer = new CatalogDrawer
|
||||
{
|
||||
LastDateModified = DateTime.Today,
|
||||
Content = result
|
||||
};
|
||||
await StoreCatalogDrawerAsync(countryCode, drawer);
|
||||
}
|
||||
_logger.LogDebug("CatalogDrawer {}", JsonSerializer.Serialize(drawer, _options));
|
||||
return drawer ?? new CatalogDrawer();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Company Info
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <param name="force"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<InfoDrawer> GetInfoDrawerAsync(string companyId, bool force = false)
|
||||
{
|
||||
var drawer = await _asyncStorageService
|
||||
.GetItemAsync<InfoDrawer>($"{companyId}.{InfoDrawer.Label}");
|
||||
|
||||
if (drawer == null) force = true;
|
||||
if (force)
|
||||
{
|
||||
var result = await _customerRepo.GetCompanyById(companyId);
|
||||
drawer = new InfoDrawer
|
||||
{
|
||||
LastDateModified = DateTime.Today,
|
||||
Content = result
|
||||
};
|
||||
await StoreInfoDrawerAsync(companyId, drawer);
|
||||
}
|
||||
_logger.LogDebug("InfoDrawer {}", JsonSerializer.Serialize(drawer, _options));
|
||||
return drawer ?? new InfoDrawer();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Inventory
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <param name="force"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<InventoryDrawer> GetInventoryDrawerAsync(string companyId, bool force = false)
|
||||
{
|
||||
var drawer = await _asyncStorageService
|
||||
.GetItemAsync<InventoryDrawer>($"{companyId}.{InventoryDrawer.Label}");
|
||||
|
||||
if (drawer == null) force = true;
|
||||
if (force)
|
||||
{
|
||||
var result = await _historyRepo.GetInventory(companyId);
|
||||
drawer = new InventoryDrawer
|
||||
{
|
||||
LastDateModified = DateTime.Today,
|
||||
Content = result
|
||||
};
|
||||
await StoreInventoryDrawerAsync(companyId, drawer);
|
||||
}
|
||||
_logger.LogDebug("InventoryDrawer {}", JsonSerializer.Serialize(drawer, _options));
|
||||
return drawer ?? new InventoryDrawer();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Invoices
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <param name="force"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<InvoiceDrawer> GetInvoiceDrawerAsync(string companyId, bool force = false)
|
||||
{
|
||||
var drawer = await _asyncStorageService
|
||||
.GetItemAsync<InvoiceDrawer>($"{companyId}.{InvoiceDrawer.Label}");
|
||||
if (drawer == null) force = true;
|
||||
if (force)
|
||||
{
|
||||
var result = await _historyRepo.GetInvoiceList(companyId);
|
||||
drawer = new InvoiceDrawer
|
||||
{
|
||||
LastDateModified = DateTime.Today,
|
||||
Content = result
|
||||
};
|
||||
await StoreInvoiceDrawerAsync(companyId, drawer);
|
||||
}
|
||||
_logger.LogDebug("InvoiceDrawer {}", JsonSerializer.Serialize(drawer, _options));
|
||||
|
||||
return drawer ?? new InvoiceDrawer();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Statistic (invoice lines)
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <param name="force"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<StatisticDrawer> GetStatisticDrawerAsync(string companyId, bool force = false)
|
||||
{
|
||||
var drawer = await _asyncStorageService
|
||||
.GetItemAsync<StatisticDrawer>($"{companyId}.{StatisticDrawer.Label}");
|
||||
|
||||
if (drawer == null) force = true;
|
||||
if (force)
|
||||
{
|
||||
var result = await _historyRepo.GetProductInvoiceLines(companyId);
|
||||
drawer = new StatisticDrawer
|
||||
{
|
||||
LastDateModified = DateTime.Today,
|
||||
Content = result
|
||||
};
|
||||
await StoreStatisticDrawerAsync(companyId, drawer);
|
||||
}
|
||||
_logger.LogDebug("StatisticDrawer {}", JsonSerializer.Serialize(drawer, _options));
|
||||
return drawer ?? new StatisticDrawer();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Store Activity
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <param name="drawer"></param>
|
||||
public async Task StoreActivityDrawerAsync(string companyId, ActivityDrawer drawer)
|
||||
{
|
||||
if (drawer.Content.Any())
|
||||
{
|
||||
drawer.Content = drawer.Content.OrderByDescending(x => x.OrderDate).ToList();
|
||||
}
|
||||
await _asyncStorageService.SetItemAsync($"{companyId}.{ActivityDrawer.Label}", drawer);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Store Sales Catalog
|
||||
/// </summary>
|
||||
/// <param name="countryCode"></param>
|
||||
/// <param name="drawer"></param>
|
||||
public async Task StoreCatalogDrawerAsync(string countryCode, CatalogDrawer drawer)
|
||||
{
|
||||
await _asyncStorageService.SetItemAsync($"{countryCode}.{CatalogDrawer.Label}", drawer);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Store Company Info
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <param name="drawer"></param>
|
||||
public async Task StoreInfoDrawerAsync(string companyId, InfoDrawer drawer)
|
||||
{
|
||||
await _asyncStorageService.SetItemAsync($"{companyId}.{InfoDrawer.Label}", drawer);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Store Inventory
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <param name="drawer"></param>
|
||||
public async Task StoreInventoryDrawerAsync(string companyId, InventoryDrawer drawer)
|
||||
{
|
||||
if (drawer.Content.Any())
|
||||
{
|
||||
drawer.Content = drawer.Content.OrderByDescending(x => x.LastInvoiceDate).ToList();
|
||||
}
|
||||
await _asyncStorageService.SetItemAsync($"{companyId}.{InventoryDrawer.Label}", drawer);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Store Invoices
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <param name="drawer"></param>
|
||||
public async Task StoreInvoiceDrawerAsync(string companyId, InvoiceDrawer drawer)
|
||||
{
|
||||
if (drawer.Content.Any())
|
||||
{
|
||||
drawer.Content = drawer.Content.OrderByDescending(x => x.DocumentDate).ToList();
|
||||
}
|
||||
await _asyncStorageService.SetItemAsync($"{companyId}.{InvoiceDrawer.Label}", drawer);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Store statistic (invoice lines)
|
||||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <param name="drawer"></param>
|
||||
public async Task StoreStatisticDrawerAsync(string companyId, StatisticDrawer drawer)
|
||||
{
|
||||
if (drawer.Content.Any())
|
||||
{
|
||||
drawer.Content = drawer.Content.OrderByDescending(x => x.DeliveryDate).ToList();
|
||||
}
|
||||
await _asyncStorageService.SetItemAsync($"{companyId}.{StatisticDrawer.Label}", drawer);
|
||||
}
|
||||
}
|
30
Wonky.Client/Local.Services/IDrawerCabinetService.cs
Normal file
30
Wonky.Client/Local.Services/IDrawerCabinetService.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System.Security.Authentication.ExtendedProtection;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Entity.DTO;
|
||||
|
||||
namespace Wonky.Client.Local.Services;
|
||||
|
||||
public interface IDrawerCabinetService
|
||||
{
|
||||
Task<ActivityDrawer> GetActivityDrawerAsync(string companyId, bool force = false);
|
||||
Task<CatalogDrawer> GetCatalogDrawerAsync(string countryCode, bool force = false);
|
||||
Task<InfoDrawer> GetInfoDrawerAsync(string companyId, bool force = false);
|
||||
Task<InventoryDrawer> GetInventoryDrawerAsync(string companyId, bool force = false);
|
||||
Task<InvoiceDrawer> GetInvoiceDrawerAsync(string companyId, bool force = false);
|
||||
Task<StatisticDrawer> GetStatisticDrawerAsync(string companyId, bool force = false);
|
||||
|
||||
Task StoreActivityDrawerAsync(string companyId, ActivityDrawer drawer);
|
||||
Task StoreCatalogDrawerAsync(string countryCode, CatalogDrawer drawer);
|
||||
Task StoreInfoDrawerAsync(string companyId, InfoDrawer drawer);
|
||||
Task StoreInventoryDrawerAsync(string companyId, InventoryDrawer drawer);
|
||||
Task StoreInvoiceDrawerAsync(string companyId, InvoiceDrawer drawer);
|
||||
Task StoreStatisticDrawerAsync(string companyId, StatisticDrawer drawer);
|
||||
|
||||
// void StoreActivityDrawer(string companyId, ActivityDrawer drawer);
|
||||
// void StoreCatalogDrawer(string countryCode, CatalogDrawer drawer);
|
||||
// void StoreInfoDrawer(string companyId, InfoDrawer drawer);
|
||||
// void StoreInventoryDrawer(string companyId, InventoryDrawer drawer);
|
||||
// void StoreInvoiceDrawer(string companyId, InvoiceDrawer drawer);
|
||||
// void StoreStatisticDrawer(string companyId, StatisticDrawer drawer);
|
||||
|
||||
}
|
|
@ -21,6 +21,7 @@ namespace Wonky.Client.Local.Services;
|
|||
public interface IUserInfoService
|
||||
{
|
||||
Task<string> GetUserId();
|
||||
Task<string> GetCountryCode();
|
||||
Task<UserManagerEditView> GetUserInfo();
|
||||
Task SetUserInfo(UserManagerEditView userInfo);
|
||||
Task<bool> IsSupervisor();
|
||||
|
|
|
@ -24,10 +24,10 @@ namespace Wonky.Client.Local.Services;
|
|||
|
||||
public class UserInfoService : IUserInfoService
|
||||
{
|
||||
private const string _infoKey = "_xui";
|
||||
private const string _refreshKey = "_xr";
|
||||
private const string _accessKey = "_xa";
|
||||
private const string _expiryKey = "_xe";
|
||||
private const string InfoKey = "_xui";
|
||||
private const string RefreshKey = "_xr";
|
||||
private const string AccessKey = "_xa";
|
||||
private const string ExpiryKey = "_xe";
|
||||
private readonly ILocalStorageService _localStorageService;
|
||||
private readonly JsonSerializerOptions _options = new() { PropertyNameCaseInsensitive = true };
|
||||
|
||||
|
@ -44,6 +44,12 @@ public class UserInfoService : IUserInfoService
|
|||
return x.UserId;
|
||||
}
|
||||
|
||||
public async Task<string> GetCountryCode()
|
||||
{
|
||||
var x = await GetUserInfo();
|
||||
return x.CountryCode;
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> IsSupervisor()
|
||||
{
|
||||
|
@ -54,48 +60,48 @@ public class UserInfoService : IUserInfoService
|
|||
|
||||
public async Task<UserManagerEditView> GetUserInfo()
|
||||
{
|
||||
return await _localStorageService.GetItemAsync<UserManagerEditView>(_infoKey);
|
||||
return await _localStorageService.GetItemAsync<UserManagerEditView>(InfoKey);
|
||||
}
|
||||
|
||||
|
||||
public async Task SetUserInfo(UserManagerEditView userInfo)
|
||||
{
|
||||
await _localStorageService.SetItemAsync(_infoKey, userInfo);
|
||||
await _localStorageService.SetItemAsync(InfoKey, userInfo);
|
||||
}
|
||||
|
||||
|
||||
public async Task<string> GetRefreshToken()
|
||||
{
|
||||
return await _localStorageService.GetItemAsStringAsync(_refreshKey);
|
||||
return await _localStorageService.GetItemAsStringAsync(RefreshKey);
|
||||
}
|
||||
|
||||
|
||||
public async Task SetRefreshToken(string token)
|
||||
{
|
||||
await _localStorageService.SetItemAsStringAsync(_refreshKey, token);
|
||||
await _localStorageService.SetItemAsStringAsync(RefreshKey, token);
|
||||
}
|
||||
|
||||
|
||||
public async Task<string> GetAccessToken()
|
||||
{
|
||||
return await _localStorageService.GetItemAsStringAsync(_accessKey);
|
||||
return await _localStorageService.GetItemAsStringAsync(AccessKey);
|
||||
}
|
||||
|
||||
|
||||
public async Task SetAccessToken(string token)
|
||||
{
|
||||
await _localStorageService.SetItemAsStringAsync(_accessKey, token);
|
||||
await _localStorageService.SetItemAsStringAsync(AccessKey, token);
|
||||
}
|
||||
|
||||
|
||||
public async Task<long> GetExpiration()
|
||||
{
|
||||
return await _localStorageService.GetItemAsync<long>(_expiryKey);
|
||||
return await _localStorageService.GetItemAsync<long>(ExpiryKey);
|
||||
}
|
||||
|
||||
|
||||
public async Task SetExpiration(long expiration)
|
||||
{
|
||||
await _localStorageService.SetItemAsync(_expiryKey, expiration);
|
||||
await _localStorageService.SetItemAsync(ExpiryKey, expiration);
|
||||
}
|
||||
}
|
11
Wonky.Client/Models/ActivityDrawer.cs
Normal file
11
Wonky.Client/Models/ActivityDrawer.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.Models;
|
||||
|
||||
public class ActivityDrawer
|
||||
{
|
||||
public const string Label = "Activity";
|
||||
public DateTime LastDateModified { get; set; }
|
||||
public List<ReportItemView> Content { get; set; } = new();
|
||||
}
|
10
Wonky.Client/Models/CatalogDrawer.cs
Normal file
10
Wonky.Client/Models/CatalogDrawer.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.Models;
|
||||
|
||||
public class CatalogDrawer
|
||||
{
|
||||
public const string Label = "Catalog";
|
||||
public DateTime LastDateModified { get; set; }
|
||||
public List<SalesItemView> Content { get; set; } = new();
|
||||
}
|
10
Wonky.Client/Models/InfoDrawer.cs
Normal file
10
Wonky.Client/Models/InfoDrawer.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using Wonky.Entity.DTO;
|
||||
|
||||
namespace Wonky.Client.Models;
|
||||
|
||||
public class InfoDrawer
|
||||
{
|
||||
public const string Label = "Info";
|
||||
public DateTime LastDateModified { get; set; }
|
||||
public CompanyDto Content { get; set; } = new();
|
||||
}
|
10
Wonky.Client/Models/InventoryDrawer.cs
Normal file
10
Wonky.Client/Models/InventoryDrawer.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.Models;
|
||||
|
||||
public class InventoryDrawer
|
||||
{
|
||||
public const string Label = "Inventory";
|
||||
public DateTime LastDateModified { get; set; }
|
||||
public List<ProductInventoryItemView> Content { get; set; } = new();
|
||||
}
|
10
Wonky.Client/Models/InvoiceDrawer.cs
Normal file
10
Wonky.Client/Models/InvoiceDrawer.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.Models;
|
||||
|
||||
public class InvoiceDrawer
|
||||
{
|
||||
public const string Label = "Invoice";
|
||||
public DateTime LastDateModified { get; set; }
|
||||
public List<InvoiceListItemView> Content { get; set; } = new();
|
||||
}
|
10
Wonky.Client/Models/StatisticDrawer.cs
Normal file
10
Wonky.Client/Models/StatisticDrawer.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.Models;
|
||||
|
||||
public class StatisticDrawer
|
||||
{
|
||||
public const string Label = "Statistic";
|
||||
public DateTime LastDateModified { get; set; }
|
||||
public List<ProductHistoryView> Content { get; set; } = new();
|
||||
}
|
|
@ -27,6 +27,22 @@ public partial class CustomerActivityListOverlay
|
|||
private string _modalDisplay = "";
|
||||
private bool _showBackdrop;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// On Paramters Set
|
||||
/// </summary>
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (Activities.Any())
|
||||
{
|
||||
Activities = Activities.OrderByDescending(x => x.OrderDate).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Show Self
|
||||
/// </summary>
|
||||
public void Show()
|
||||
{
|
||||
_modalDisplay = "block;";
|
||||
|
@ -34,6 +50,10 @@ public partial class CustomerActivityListOverlay
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Hide Self
|
||||
/// </summary>
|
||||
private void Hide()
|
||||
{
|
||||
_modalDisplay = "none;";
|
||||
|
|
|
@ -18,11 +18,15 @@
|
|||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3>Besøg</h3>
|
||||
<button type="button" class="btn btn-danger" @onclick="@Hide" data-bs-dismiss="modal" aria-label="Luk"><i class="bi-x-lg"></i></button>
|
||||
<button type="button" class="btn btn-danger" @onclick="@Hide" data-bs-dismiss="modal" aria-label="Luk">
|
||||
<i class="bi-x-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@if (!string.IsNullOrWhiteSpace(ReportItem.Company.Name))
|
||||
{
|
||||
<div class="card-title mb-2">
|
||||
<h3>@ReportItem.Company.Name</h3>
|
||||
</div>
|
||||
|
@ -96,6 +100,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -25,6 +25,10 @@ public partial class CustomerActivityViewOverlay
|
|||
private string _modalDisplay = "";
|
||||
private bool _showBackdrop;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Show Self
|
||||
/// </summary>
|
||||
public void Show()
|
||||
{
|
||||
_modalDisplay = "block;";
|
||||
|
@ -32,6 +36,10 @@ public partial class CustomerActivityViewOverlay
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Hide Self
|
||||
/// </summary>
|
||||
private void Hide()
|
||||
{
|
||||
_modalDisplay = "none;";
|
||||
|
|
|
@ -25,31 +25,47 @@ namespace Wonky.Client.OverlayCustomer;
|
|||
|
||||
public partial class CustomerInventoryListOverlay : IDisposable
|
||||
{
|
||||
/*
|
||||
* Dependency Injection
|
||||
*/
|
||||
[Inject] public ILogger<CustomerInventoryListOverlay> Logger { get; set; }
|
||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] public ICountryCatalogRepository CatalogRepo { get; set; }
|
||||
[Inject] public ILogger<CustomerInventoryListOverlay> Logger { get; set; }
|
||||
|
||||
/*
|
||||
* Parameters
|
||||
*/
|
||||
[Parameter] public string CompanyName { get; set; } = "";
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
[Parameter] public string CountryCode { get; set; } = "";
|
||||
[Parameter] public List<ProductInventoryItemView> Inventory { get; set; } = new();
|
||||
|
||||
[Parameter] public EventCallback<DraftItem> OnSelected { get; set; }
|
||||
|
||||
/*
|
||||
* Private Variables
|
||||
*/
|
||||
private string _modalDisplay = "";
|
||||
private bool _showBackdrop;
|
||||
private CompanyDto Company { get; set; } = new();
|
||||
// private List<ProductInventoryView> ProductList { get; set; } = new();
|
||||
private DraftItem DraftItem { get; set; } = new();
|
||||
private SalesItemView SalesItem { get; set; } = new();
|
||||
private CustomerInventoryReorderOverlay ReorderOverlay { get; set; } = new();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// On Parameters Set
|
||||
/// </summary>
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if(Inventory.Any())
|
||||
Inventory = Inventory.OrderBy(x => x.Description).ToList();
|
||||
{
|
||||
Inventory = Inventory
|
||||
.OrderByDescending(x => x.LastInvoiceDate)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// On Initialized
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Interceptor.RegisterEvent();
|
||||
|
@ -57,18 +73,32 @@ public partial class CustomerInventoryListOverlay : IDisposable
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Inventory Reorder Overlay Callback
|
||||
/// </summary>
|
||||
/// <param name="sku"></param>
|
||||
private async Task OnReorderCallback(string sku)
|
||||
{
|
||||
SalesItem = await CatalogRepo.GetSalesItemSku(CountryCode.ToLower(), sku);
|
||||
ReorderOverlay.Show();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// SelectedItem Callback
|
||||
/// </summary>
|
||||
/// <param name="draftItem"></param>
|
||||
private async Task OnSelectedItem(DraftItem draftItem)
|
||||
{
|
||||
await OnSelected.InvokeAsync(draftItem);
|
||||
Hide();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Show Self
|
||||
/// </summary>
|
||||
public void Show()
|
||||
{
|
||||
_modalDisplay = "block;";
|
||||
|
@ -76,6 +106,10 @@ public partial class CustomerInventoryListOverlay : IDisposable
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Hide Self
|
||||
/// </summary>
|
||||
private void Hide()
|
||||
{
|
||||
_modalDisplay = "none;";
|
||||
|
@ -83,6 +117,10 @@ public partial class CustomerInventoryListOverlay : IDisposable
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Dispose Self
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Interceptor.DisposeEvent();
|
||||
|
|
|
@ -42,6 +42,9 @@ public partial class CustomerInventoryReorderOverlay
|
|||
private bool ShowDraft { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// On Parameters Set Async
|
||||
/// </summary>
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(SalesItem.Sku))
|
||||
|
@ -57,6 +60,11 @@ public partial class CustomerInventoryReorderOverlay
|
|||
SelectedItem.Price = decimal.Parse(SalesItem.Rates[0].Rate, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Invoke Callback Adding Selected Item To Draft
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
private async Task SendToOrder(DraftItem item)
|
||||
{
|
||||
SelectedItem = new DraftItem();
|
||||
|
@ -64,6 +72,12 @@ public partial class CustomerInventoryReorderOverlay
|
|||
Hide();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Apply Selected Price To Item
|
||||
/// </summary>
|
||||
/// <param name="quantity"></param>
|
||||
/// <param name="rate"></param>
|
||||
private void SelectPrice(string quantity, string rate)
|
||||
{
|
||||
SelectedItem.Discount = 0;
|
||||
|
@ -72,6 +86,11 @@ public partial class CustomerInventoryReorderOverlay
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Apply Selected Historical Price To Item
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
private void SelectHistory(ProductHistoryView item)
|
||||
{
|
||||
SelectedItem.Discount = item.Discount;
|
||||
|
@ -80,6 +99,10 @@ public partial class CustomerInventoryReorderOverlay
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Show Self
|
||||
/// </summary>
|
||||
public void Show()
|
||||
{
|
||||
_modalDisplay = "block;";
|
||||
|
@ -87,6 +110,10 @@ public partial class CustomerInventoryReorderOverlay
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reset SelectedItem And Hide Self
|
||||
/// </summary>
|
||||
private void Hide()
|
||||
{
|
||||
SelectedItem = new DraftItem();
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<button type="button" class="btn btn-danger" @onclick="@Hide" data-bs-dismiss="modal" aria-label="Luk"><i class="bi-x-lg"></i></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<CustomerInvoiceListComponent OnShowInvoice="@CallInvoiceModal" CompanyId="@Company.CompanyId" InvoiceList="@Invoices"/>
|
||||
<CustomerInvoiceListComponent OnShowInvoice="@CallInvoiceModal" Invoices="@Invoices"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Views;
|
||||
#pragma warning disable CS8618
|
||||
|
||||
|
@ -23,36 +24,46 @@ namespace Wonky.Client.OverlayCustomer;
|
|||
|
||||
public partial class CustomerInvoiceListOverlay
|
||||
{
|
||||
[Parameter] public InvoiceListView CustomerInvoices { get; set; } = new();
|
||||
|
||||
// ##############################################################
|
||||
[Inject] public ILogger<CustomerInvoiceListOverlay> Logger { get; set; }
|
||||
|
||||
// ##############################################################
|
||||
[Parameter] public List<InvoiceListItemView> Invoices { get; set; } = new();
|
||||
[Parameter] public CompanyDto Company { get; set; } = new();
|
||||
|
||||
// ##############################################################
|
||||
private CustomerInvoiceViewOverlay CustomerInvoiceView { get; set; } = new();
|
||||
private string InvoiceId { get; set; } = "";
|
||||
private string _modalDisplay = "";
|
||||
private bool _showBackdrop;
|
||||
private List<InvoiceListItemView> Invoices { get; set; } = new();
|
||||
private InvoiceCompanyView Company { get; set; } = new();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// On Parameters Set
|
||||
/// </summary>
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
Company = CustomerInvoices.Company;
|
||||
Logger.LogDebug("company => {}", JsonSerializer.Serialize(Company));
|
||||
if (CustomerInvoices.Invoices.Any())
|
||||
Invoices = CustomerInvoices.Invoices.OrderByDescending(x => x.DocumentDate).ToList();
|
||||
Logger.LogDebug("invoices => {}", JsonSerializer.Serialize(Invoices));
|
||||
if (Invoices.Any())
|
||||
Invoices = Invoices
|
||||
.OrderByDescending(x => x.DocumentDate)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show Invoice View Overlay
|
||||
/// </summary>
|
||||
/// <param name="invoiceId"></param>
|
||||
private void CallInvoiceModal(string invoiceId)
|
||||
{
|
||||
InvoiceId = invoiceId;
|
||||
CustomerInvoiceView.Show();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Show Self
|
||||
/// </summary>
|
||||
public void Show()
|
||||
{
|
||||
_modalDisplay = "block;";
|
||||
|
@ -60,6 +71,10 @@ public partial class CustomerInvoiceListOverlay
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Hide Self
|
||||
/// </summary>
|
||||
private void Hide()
|
||||
{
|
||||
_modalDisplay = "none;";
|
||||
|
|
|
@ -37,6 +37,10 @@ public partial class CustomerInvoiceViewOverlay : IDisposable
|
|||
private bool _showBackdrop;
|
||||
private InvoiceView Invoice { get; set; } = new();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// On Parameters Set Async
|
||||
/// </summary>
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
Interceptor.RegisterEvent();
|
||||
|
@ -44,10 +48,14 @@ public partial class CustomerInvoiceViewOverlay : IDisposable
|
|||
|
||||
if (!string.IsNullOrWhiteSpace(InvoiceId))
|
||||
{
|
||||
Invoice = await HistoryRepo.FetchInvoice(CompanyId, InvoiceId);
|
||||
Invoice = await HistoryRepo.GetInvoice(CompanyId, InvoiceId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Show Self
|
||||
/// </summary>
|
||||
public void Show()
|
||||
{
|
||||
_modalDisplay = "block;";
|
||||
|
@ -55,6 +63,10 @@ public partial class CustomerInvoiceViewOverlay : IDisposable
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Hide Self
|
||||
/// </summary>
|
||||
private void Hide()
|
||||
{
|
||||
_modalDisplay = "none;";
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
@* component listing invoices*@
|
||||
<CustomerInvoiceListComponent OnShowInvoice="@CallInvoiceModal" CompanyId="@Company.CompanyId" InvoiceList="@Invoices"/>
|
||||
<CustomerInvoiceListComponent OnShowInvoice="@CallInvoiceModal" CompanyId="@Company.CompanyId" Invoices="@Invoices"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -19,7 +19,7 @@ using Wonky.Entity.Views;
|
|||
|
||||
namespace Wonky.Client.OverlayOrderCreate;
|
||||
|
||||
public partial class ProductCheckConfirmationOverlay
|
||||
public partial class ConfirmCheckOverlay
|
||||
{
|
||||
// ##############################################################
|
||||
[Parameter] public string BodyMessage { get; set; } = "";
|
|
@ -57,7 +57,7 @@ else
|
|||
<label for="activityType" class="col-sm-2 col-form-label-sm">Ordre Type</label>
|
||||
<div class="col-sm-4">
|
||||
<InputSelect id="activityType" class="form-select bg-primary text-bg-primary" @bind-Value="@Activity.ActivityTypeEnum">
|
||||
@if (Kanvas)
|
||||
@if (_kanvas)
|
||||
{
|
||||
<option value="canvas" selected>Kanvas</option>
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ else
|
|||
<label for="statusType" class="col-sm-2 col-form-label-sm">Status</label>
|
||||
<div class="col-sm-4">
|
||||
<InputSelect id="statusType" class="form-select bg-primary text-bg-primary" @bind-Value="@Activity.ActivityStatusEnum">
|
||||
@if (Kanvas)
|
||||
@if (_kanvas)
|
||||
{
|
||||
<option value="canvas" selected>Kanvas</option>
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ else
|
|||
}
|
||||
</div>
|
||||
|
||||
@if (Kanvas)
|
||||
@if (_kanvas)
|
||||
{
|
||||
<label for="demo" class="col-sm-2 col-form-label-sm">Demo</label>
|
||||
<div class="col-sm-10">
|
||||
|
@ -188,7 +188,7 @@ else
|
|||
}
|
||||
</div>
|
||||
|
||||
@if (!Kanvas)
|
||||
@if (!_kanvas)
|
||||
{
|
||||
<div class="row g-2 mb-3">
|
||||
<div class="col-sm-3 d-grid mx-auto">
|
||||
|
@ -201,7 +201,7 @@ else
|
|||
@*
|
||||
***************** Visit hisotry overlay *****************************
|
||||
*@
|
||||
<button class="btn btn-warning" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" @onclick="@ShowVisitOverlay">Tidl. besøg</button>
|
||||
<button class="btn btn-warning" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" @onclick="@ShowActivitiesOverlay">Tidl. besøg</button>
|
||||
</div>
|
||||
<div class="col-sm-3 d-grid mx-auto">
|
||||
@*
|
||||
|
@ -272,7 +272,7 @@ else
|
|||
@*
|
||||
***************** Price catalog overlay button *****************************
|
||||
*@
|
||||
<button class="btn btn-primary" type="button" @onclick="@ShowPriceListOverlay">
|
||||
<button class="btn btn-primary" type="button" @onclick="@ShowPriceCatalogOverlay">
|
||||
<i class="bi-plus"></i> Ny linje
|
||||
</button>
|
||||
</td>
|
||||
|
@ -345,7 +345,7 @@ else
|
|||
Leveringsadresse
|
||||
</button>
|
||||
</div>
|
||||
<div class="@(HideDeliveryAddress ? "inno-hidden" : "inno-display")">
|
||||
<div class="@(_hideDeliveryAddress ? "inno-hidden" : "inno-display")">
|
||||
<div class="card-body">
|
||||
<div class="row mb-1">
|
||||
<label for="dlvName" class="col-sm-2 col-form-label-sm">Lev. Navn</label>
|
||||
|
@ -380,51 +380,6 @@ else
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@*</div>*@
|
||||
@*<div class="accordion" id="crmActivity">
|
||||
$1$ Delivery address #1#
|
||||
<div class="accordion-item @(Activity.ActivityStatusEnum == "order" ? "inno-display" : "inno-hidden")">
|
||||
<h2 class="accordion-header" id="deliveryHeader">
|
||||
<button class="accordion-button bg-light" type="button" data-bs-toggle="collapse" data-bs-target="#deliveryBody" aria-expanded="false" aria-controls="deliveryBody">
|
||||
Leveringsadresse
|
||||
</button>
|
||||
</h2>
|
||||
<div id="deliveryBody" class="accordion-collapse collapsed" aria-labelledby="deliveryHeader" data-bs-parent="#crmActivity">
|
||||
<div class="accordion-body">
|
||||
<div class="row mb-1">
|
||||
<label for="dlvName" class="col-sm-2 col-form-label-sm">Lev. Navn</label>
|
||||
<div class="col-md-10">
|
||||
<InputText id="dlvName" class="form-control" @bind-Value="Activity.DlvName"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label for="dlvAddress1" class="col-sm-2 col-form-label-sm">Lev. Adresse</label>
|
||||
<div class="col-md-10">
|
||||
<InputText id="dlvAddress1" class="form-control" @bind-Value="Activity.DlvAddress1"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label for="dlvAddress2" class="col-sm-2 col-form-label-sm">Lev. Adresse</label>
|
||||
<div class="col-md-10">
|
||||
<InputText id="dlvAddress2" class="form-control" @bind-Value="Activity.DlvAddress2"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label for="dlvZipCode" class="col-sm-2 col-form-label-sm">Lev. Postnr</label>
|
||||
<div class="col-md-10">
|
||||
<InputText id="dlvZipCode" class="form-control" @bind-Value="Activity.DlvZipCode"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label for="dlvCity" class="col-sm-2 col-form-label-sm">Lev. Bynavn</label>
|
||||
<div class="col-md-10">
|
||||
<InputText id="dlvCity" class="form-control" @bind-Value="Activity.DlvCity"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>*@
|
||||
}
|
||||
</EditForm>
|
||||
|
||||
|
@ -437,27 +392,35 @@ else
|
|||
***************** Confirm product check overlay button *****************************
|
||||
***************** Continue by submitton order to erp *****************************
|
||||
*@
|
||||
<button type="button" class="btn btn-warning" @onclick="@CallConfirmCheckOverlay" disabled="@(PoFormInvalid || Working)">
|
||||
<button type="button" class="btn btn-warning" @onclick="@ShowProductCheckOverlay" disabled="@(PoFormInvalid || Working)">
|
||||
<i class="bi-cloud-arrow-up"></i> @ButtonText
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<ProductCheckConfirmationOverlay BodyMessage="" CompanyId="@CompanyId" Products="CheckList"
|
||||
OnOkClicked="ConfirmProductCheckCallback" @ref="ConfirmationCheckOverlay"/>
|
||||
<ConfirmWorkDateModal BodyMessage="@PromptDateConfirm"
|
||||
OnOkClicked="WorkDateConfirmCallback" @ref="ConfirmWorkDate"/>
|
||||
<ConfirmWorkDateOverlay BodyMessage="@PromptDateConfirm"
|
||||
OnOkClicked="WorkDateOverlayCallback" @ref="WorkDateOverlay"/>
|
||||
|
||||
<ProductHistoryOverlay CompanyId="@CompanyId" ItemSku="@SelectedItem.Sku" @ref="ProductOverlay"/>
|
||||
|
||||
<CatalogPagedOverlay CountryCode="@Company.CountryCode.ToLower()" OnSelected="PriceListCallback" @ref="CatalogOverlay"/>
|
||||
<CatalogPagedOverlay CountryCode="@Company.CountryCode.ToLower()"
|
||||
OnSelected="PriceCatalogOverlayCallback" @ref="CatalogOverlay"/>
|
||||
|
||||
<ProductPriceHistoryOverlay CompanyId="@CompanyId" Sku="@SelectedItem.Sku" OnSelected="PriceHistoryCallback" @ref="PriceOverlay"/>
|
||||
<ProductPriceHistoryOverlay CompanyId="@CompanyId" Sku="@SelectedItem.Sku"
|
||||
OnSelected="PriceHistoryOverlayCallback" @ref="PriceOverlay"/>
|
||||
|
||||
<CustomerInvoiceListOverlay CustomerInvoices="CompanyInvoices" @ref="InvoiceListOverlay"/>
|
||||
<ConfirmCheckOverlay BodyMessage="" CompanyId="@CompanyId"
|
||||
Products="_inventoryDrawer.Content"
|
||||
OnOkClicked="ProductCheckOverlayCallback" @ref="ProductCheckOverlay"/>
|
||||
|
||||
<CustomerActivityListOverlay Activities="Activities" CompanyName="@Company.Name" @ref="ActivityListOverlay"/>
|
||||
<CustomerActivityListOverlay CompanyName="@Company.Name"
|
||||
Activities="_activityDrawer.Content" @ref="ActivityListOverlay"/>
|
||||
|
||||
<CustomerInventoryListOverlay CompanyName="@Company.Name" CompanyId="@CompanyId" CountryCode="@Company.CountryCode"
|
||||
OnSelected="OnInventoryCallback" Inventory="Inventory" @ref="InventoryListOverlay"/>
|
||||
Inventory="_inventoryDrawer.Content"
|
||||
OnSelected="InventoryOverlayCallback" @ref="InventoryListOverlay"/>
|
||||
|
||||
<CustomerInvoiceListOverlay Company="Company"
|
||||
Invoices="_invoiceDrawer.Content" @ref="InvoiceListOverlay"/>
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
[Inject] public ICrmSalesReportRepository ReportRepo { get; set; }
|
||||
[Inject] public ICrmCustomerHistoryRepository HistoryRepo { get; set; }
|
||||
[Inject] public IUserInfoService UserInfo { get; set; }
|
||||
[Inject] public IDrawerCabinetService CabinetService { get; set; }
|
||||
|
||||
// #############################################################
|
||||
[CascadingParameter] private DraftStateProvider DraftProvider { get; set; } = new();
|
||||
|
@ -74,30 +75,25 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
private bool Working { get; set; } = true;
|
||||
private UserManagerEditView SalesRep { get; set; } = new();
|
||||
private DateTime SelectedDate { get; set; }
|
||||
// private string OldPhone { get; set; } = "";
|
||||
private string PromptDateConfirm { get; set; } = "";
|
||||
private string ButtonText { get; set; } = "Gem besøg";
|
||||
private bool OrgWarning { get; set; }
|
||||
|
||||
private const string PromptDemoForgotten = "Har du glemt demo?";
|
||||
|
||||
// #############################################################
|
||||
private CatalogPagedOverlay CatalogOverlay { get; set; } = new();
|
||||
private ProductHistoryOverlay ProductOverlay { get; set; } = new();
|
||||
private ProductPriceHistoryOverlay PriceOverlay { get; set; } = new();
|
||||
private ConfirmWorkDateModal ConfirmWorkDate { get; set; } = new();
|
||||
private ProductCheckConfirmationOverlay ConfirmationCheckOverlay { get; set; } = new();
|
||||
private ConfirmWorkDateOverlay WorkDateOverlay { get; set; } = new();
|
||||
private ConfirmCheckOverlay ProductCheckOverlay { get; set; } = new();
|
||||
private CustomerInvoiceListOverlay InvoiceListOverlay { get; set; } = new();
|
||||
private CustomerInventoryListOverlay InventoryListOverlay { get; set; } = new();
|
||||
private CustomerActivityListOverlay ActivityListOverlay { get; set; } = new();
|
||||
private bool _kanvas;
|
||||
private bool _hideDeliveryAddress = true;
|
||||
private InfoDrawer _infoDrawer = new();
|
||||
private ActivityDrawer _activityDrawer = new();
|
||||
private InventoryDrawer _inventoryDrawer = new();
|
||||
private InvoiceDrawer _invoiceDrawer = new();
|
||||
|
||||
// #############################################################
|
||||
private List<ProductInventoryItemView> Inventory { get; set; } = new();
|
||||
private List<ProductInventoryItemView> CheckList { get; set; } = new();
|
||||
private InvoiceListView CompanyInvoices { get; set; } = new();
|
||||
private List<ReportItemView> Activities { get; set; } = new();
|
||||
private bool Kanvas { get; set; }
|
||||
private bool HideDeliveryAddress { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Page initialization
|
||||
|
@ -114,12 +110,17 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
UserPreference = await PreferenceService.GetProfile();
|
||||
// User Info
|
||||
SalesRep = await UserInfo.GetUserInfo();
|
||||
// Fetch Customer from http
|
||||
Company = await CompanyRepo.GetCompanyById(CompanyId);
|
||||
|
||||
_infoDrawer = await CabinetService.GetInfoDrawerAsync(CompanyId);
|
||||
_activityDrawer = await CabinetService.GetActivityDrawerAsync(CompanyId);
|
||||
_inventoryDrawer = await CabinetService.GetInventoryDrawerAsync(CompanyId);
|
||||
_invoiceDrawer = await CabinetService.GetInvoiceDrawerAsync(CompanyId);
|
||||
|
||||
Company = _infoDrawer.Content;
|
||||
|
||||
if (Company.Account.StartsWith("KANVAS"))
|
||||
{
|
||||
Kanvas = true;
|
||||
|
||||
_kanvas = true;
|
||||
Activity.ActivityStatusEnum = "canvas";
|
||||
Activity.ActivityTypeEnum = "canvas";
|
||||
Activity.ActivityVisitEnum = "new";
|
||||
|
@ -132,19 +133,12 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
// Company has shut down
|
||||
Activity.OrderMessage = "BEMÆRK: CVR nummer er ophørt.";
|
||||
}
|
||||
//
|
||||
// if (Company.CountryCode.ToLower() == "dk"
|
||||
// && string.IsNullOrWhiteSpace(Company.Phone)
|
||||
// && !string.IsNullOrWhiteSpace(Company.Account)
|
||||
// && !Company.Account.StartsWith("NY")
|
||||
// && Company.Account.Length > 7)
|
||||
// {
|
||||
// Company.Phone = Company.Account[..8];
|
||||
// }
|
||||
|
||||
Activity.ActivityStatusEnum = "noSale";
|
||||
// decide if new or recall
|
||||
Activity.ActivityVisitEnum = Company.Account.StartsWith("NY")
|
||||
? "new" : "recall";
|
||||
? "new"
|
||||
: "recall";
|
||||
if (string.IsNullOrWhiteSpace(Company.Segment) && SalesRep.CountryCode.ToLower() == "dk")
|
||||
{
|
||||
Toaster.ShowError("Der mangler information om Segment. Ret kunde segment, gem erp data og prøv igen.");
|
||||
|
@ -190,7 +184,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
if (!UserPreference.DateConfirmed)
|
||||
{
|
||||
PromptDateConfirm = $"Aktiviteter oprettes med dato {SelectedDate.ToShortDateString()}. Er dette OK?";
|
||||
ConfirmWorkDate.Show();
|
||||
WorkDateOverlay.Show();
|
||||
}
|
||||
|
||||
// Lines may already have been added from the company inventory page
|
||||
|
@ -211,43 +205,37 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
}
|
||||
|
||||
|
||||
// #############################################################
|
||||
// overlays
|
||||
private async Task ShowVisitOverlay()
|
||||
/// <summary>
|
||||
/// Show Activity Overlay
|
||||
/// </summary>
|
||||
private void ShowActivitiesOverlay()
|
||||
{
|
||||
Logger.LogDebug("ShowInventoryOverlay - wait for visits");
|
||||
ActivityListOverlay.Show();
|
||||
Activities = await ActivityRepo.GetCustomerActivities(CompanyId);
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
|
||||
private async Task ShowInventoryOverlay()
|
||||
/// <summary>
|
||||
/// Show Inventory Overlay
|
||||
/// </summary>
|
||||
private void ShowInventoryOverlay()
|
||||
{
|
||||
Logger.LogDebug("ShowInventoryOverlay - wait for inventory");
|
||||
InventoryListOverlay.Show();
|
||||
Inventory = await HistoryRepo.FetchInventory(CompanyId);
|
||||
Inventory = Inventory.OrderBy(x => x.Description).ToList();
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
|
||||
private async Task ShowInvoiceOverlay()
|
||||
/// <summary>
|
||||
/// Show Invoice Overlay
|
||||
/// </summary>
|
||||
private void ShowInvoiceOverlay()
|
||||
{
|
||||
Logger.LogDebug("ShowInvoiceOverlay - wait for invoices");
|
||||
InvoiceListOverlay.Show();
|
||||
CompanyInvoices = await FetchCompanyInvoices();
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
|
||||
private void ShowPriceListOverlay()
|
||||
{
|
||||
CatalogOverlay.Show();
|
||||
}
|
||||
|
||||
|
||||
private async Task CallConfirmCheckOverlay()
|
||||
/// <summary>
|
||||
/// Show Product Check Overlay
|
||||
/// </summary>
|
||||
private async Task ShowProductCheckOverlay()
|
||||
{
|
||||
// check if new account
|
||||
if (string.IsNullOrWhiteSpace(Company.Account)
|
||||
|
@ -260,58 +248,22 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
return;
|
||||
}
|
||||
|
||||
// check if product has been checked
|
||||
// fetch products from storage
|
||||
var pStorage = await Storage.GetItemAsStringAsync($"{CompanyId}-products");
|
||||
Logger.LogDebug("pStorage => {}", pStorage);
|
||||
// fetch pDate from storage
|
||||
var pDate = await Storage.GetItemAsync<string>($"{CompanyId}-pDate");
|
||||
if (string.IsNullOrWhiteSpace(pDate))
|
||||
{
|
||||
pDate = $"{DateTime.Now.AddDays(-1):yyyy-MM-dd}";
|
||||
}
|
||||
Logger.LogDebug("pDate => {}", pDate);
|
||||
|
||||
// check if product data is valid and updated today
|
||||
if (string.IsNullOrWhiteSpace(pStorage) || pDate.Replace("\"", "") != $"{DateTime.Now:yyyy-MM-dd}")
|
||||
{
|
||||
Working = true;
|
||||
// pop a message
|
||||
Toaster.ShowInfo(
|
||||
"Produkt gennemgang mangler. Vent mens produkt oversigt indlæses. Gå ikke væk fra siden!");
|
||||
// product inventory has not been updated
|
||||
// request backend to sync ERP to CRM
|
||||
Toaster.ShowInfo("Vent mens data synkroniseres ...");
|
||||
var ts = await HistoryRepo.GetRecycledInvoiceList(CompanyId, Company.HistorySync, false);
|
||||
await Task.Delay(250);
|
||||
// save pDate
|
||||
await Storage.SetItemAsync($"{CompanyId}-pDate", ts);
|
||||
// request products from backend
|
||||
Toaster.ShowInfo("Vent mens produkt oversigt hentes");
|
||||
|
||||
CheckList = await HistoryRepo.FetchInventory(CompanyId);
|
||||
if (CheckList.Any())
|
||||
{
|
||||
CheckList = CheckList.OrderBy(x => x.Description).ToList();
|
||||
}
|
||||
await Storage.SetItemAsync($"{CompanyId}-products", CheckList);
|
||||
Working = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// deserialize storage data
|
||||
CheckList = JsonSerializer.Deserialize<List<ProductInventoryItemView>>(pStorage) ?? new List<ProductInventoryItemView>();
|
||||
if (CheckList.Any())
|
||||
{
|
||||
CheckList = CheckList.OrderBy(x => x.Description).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
// Show CheckList modal
|
||||
ConfirmationCheckOverlay.Show();
|
||||
ProductCheckOverlay.Show();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Show Price Catalog Overlay
|
||||
/// </summary>
|
||||
private void ShowPriceCatalogOverlay()
|
||||
{
|
||||
CatalogOverlay.Show();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Show Product Price History Overlay
|
||||
/// </summary>
|
||||
private void ShowPriceHistoryOverlay()
|
||||
{
|
||||
if (ShowItem)
|
||||
|
@ -321,16 +273,18 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
}
|
||||
|
||||
|
||||
// #############################################################
|
||||
// callbacks
|
||||
// pricelist callback
|
||||
private async Task PriceListCallback(SelectedSku sku)
|
||||
/// <summary>
|
||||
/// Price Catalog Overlay Callback
|
||||
/// </summary>
|
||||
/// <param name="sku"></param>
|
||||
private async Task PriceCatalogOverlayCallback(SelectedSku sku)
|
||||
{
|
||||
// get selected item
|
||||
if (string.IsNullOrWhiteSpace(sku.ItemId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SelectedItem = await CatalogRepo.GetSalesItemId(SalesRep.CountryCode.ToLower(), sku.ItemId);
|
||||
ShowItem = true;
|
||||
Price = sku.Rate;
|
||||
|
@ -338,19 +292,28 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
// price history callback
|
||||
private void PriceHistoryCallback(decimal price)
|
||||
|
||||
/// <summary>
|
||||
/// Product Price History Overlay Callback
|
||||
/// </summary>
|
||||
/// <param name="price"></param>
|
||||
private void PriceHistoryOverlayCallback(decimal price)
|
||||
{
|
||||
if (price == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Price = price.ToString("N2", CultureInfo.InvariantCulture);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
// inventory callback
|
||||
private void OnInventoryCallback(DraftItem item)
|
||||
|
||||
/// <summary>
|
||||
/// Inventory Overlay Callback
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
private void InventoryOverlayCallback(DraftItem item)
|
||||
{
|
||||
Activity.ActivityStatusEnum = "order";
|
||||
DraftProvider.Draft.DraftType = "order";
|
||||
|
@ -358,28 +321,38 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
StateHasChanged();
|
||||
}
|
||||
|
||||
// confirm product check callback
|
||||
private async Task ConfirmProductCheckCallback()
|
||||
|
||||
/// <summary>
|
||||
/// Product Check Overlay Callback
|
||||
/// </summary>
|
||||
private async Task ProductCheckOverlayCallback()
|
||||
{
|
||||
ConfirmationCheckOverlay.Hide();
|
||||
foreach (var item in CheckList)
|
||||
ProductCheckOverlay.Hide();
|
||||
foreach (var item in _inventoryDrawer.Content)
|
||||
{
|
||||
item.Check = false;
|
||||
}
|
||||
await Storage.SetItemAsync($"{CompanyId}-products", CheckList);
|
||||
await CabinetService.StoreInventoryDrawerAsync(CompanyId, _inventoryDrawer);
|
||||
|
||||
await CreateActivity();
|
||||
}
|
||||
|
||||
// workdate confirm callback
|
||||
private async Task WorkDateConfirmCallback()
|
||||
/// <summary>
|
||||
/// Workdate Overlay Callback
|
||||
/// </summary>
|
||||
private async Task WorkDateOverlayCallback()
|
||||
{
|
||||
await PreferenceService.SetDateConfirmed(true);
|
||||
Activity.ActivityDate = $"{SelectedDate:yyyy-MM-dd}";
|
||||
ConfirmWorkDate.Hide();
|
||||
WorkDateOverlay.Hide();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
// workdate changed callback
|
||||
|
||||
/// <summary>
|
||||
/// Workdate Changed Callback
|
||||
/// </summary>
|
||||
/// <param name="workDate"></param>
|
||||
private async Task WorkDateChangedCallback(string workDate)
|
||||
{
|
||||
ReportClosed = await ReportRepo.ReportExist(workDate);
|
||||
|
@ -388,44 +361,9 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
}
|
||||
|
||||
|
||||
// ################################################################################################
|
||||
// fetch invoices for customer
|
||||
// save invoices to storage
|
||||
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(250);
|
||||
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
|
||||
/// <summary>
|
||||
/// Create Activity
|
||||
/// </summary>
|
||||
private async Task CreateActivity()
|
||||
{
|
||||
// avoid duplication
|
||||
|
@ -433,9 +371,10 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// working flag is raised after the following validations
|
||||
Logger.LogDebug("view kanvas activity => {}", JsonSerializer.Serialize(Activity));
|
||||
switch (Kanvas)
|
||||
switch (_kanvas)
|
||||
{
|
||||
// validate customer address1
|
||||
// - this is a required input
|
||||
|
@ -466,6 +405,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
Toaster.ShowError("Ved tilbud skal en gyldig email adresse angives.");
|
||||
return;
|
||||
}
|
||||
|
||||
// every checks
|
||||
// raise working flag
|
||||
Working = true;
|
||||
|
@ -486,6 +426,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
{
|
||||
Activity.OurRef = $"E{Activity.OurRef}";
|
||||
}
|
||||
|
||||
// begin lines
|
||||
Activity.Lines = new List<ActivityLineDto>();
|
||||
var ln = 0;
|
||||
|
@ -507,6 +448,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
.ToList();
|
||||
Activity.Lines = lines;
|
||||
}
|
||||
|
||||
// debug logging
|
||||
Logger.LogDebug("CrmNewActivityPage => \n {}", JsonSerializer.Serialize(Activity));
|
||||
// post to api
|
||||
|
@ -529,21 +471,30 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Toggle Delivery Address Input
|
||||
/// </summary>
|
||||
private void ToggleDeliveryAddress()
|
||||
{
|
||||
HideDeliveryAddress = !HideDeliveryAddress;
|
||||
_hideDeliveryAddress = !_hideDeliveryAddress;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Show Incomplete Organization Number Warning
|
||||
/// </summary>
|
||||
private void ShowOrgWarning()
|
||||
{
|
||||
if (Kanvas)
|
||||
if (_kanvas)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (OrgWarning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OrgWarning = true;
|
||||
if (Company.CountryCode.ToLower() == "se"
|
||||
&& Utils.StringToDigits(Activity.VatNumber).Length < 10
|
||||
|
@ -554,8 +505,9 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
}
|
||||
|
||||
|
||||
// ###############################################################################
|
||||
// draft functions
|
||||
/// <summary>
|
||||
/// Remove Current Draft
|
||||
/// </summary>
|
||||
private async Task DeleteDraft()
|
||||
{
|
||||
await DraftProvider.DeleteDraftAsync();
|
||||
|
@ -563,6 +515,10 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add Item To Draft
|
||||
/// </summary>
|
||||
/// <param name="salesItem"></param>
|
||||
private async Task AddItem(SalesItemView salesItem)
|
||||
{
|
||||
ShowItem = false;
|
||||
|
@ -586,11 +542,16 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
{
|
||||
Activity.ActivityStatusEnum = "order";
|
||||
}
|
||||
|
||||
// save the item using the CartStateProvider's save method
|
||||
await DraftProvider.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Remove Item From Draft
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
private async Task RemoveItem(DraftItem item)
|
||||
{
|
||||
// remove item
|
||||
|
@ -604,8 +565,12 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
}
|
||||
|
||||
|
||||
// ##################################################################################################
|
||||
// form validation
|
||||
/// <summary>
|
||||
/// EditContext Field Changed Callback
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
|
||||
{
|
||||
Logger.LogDebug("ActivityNewPage => HandleFieldChanged => ActivityStatusEnum <= '{}'",
|
||||
|
@ -644,6 +609,11 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// EditContext ValdiationChanged Callback
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Activity.ActivityTypeEnum) && !ReportClosed)
|
||||
|
@ -671,8 +641,9 @@ public partial class AdvisorActivityCreatePage : IDisposable
|
|||
}
|
||||
|
||||
|
||||
// #########################################################################################################
|
||||
// dispose
|
||||
/// <summary>
|
||||
/// Dispose
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Interceptor.DisposeEvent();
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<CustomerActivityListComponent Activities="ActivityList"/>
|
||||
<CustomerActivityListComponent Activities="Activities"/>
|
||||
}
|
||||
@if (Working)
|
||||
{
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Wonky.Client.HttpInterceptors;
|
||||
using Wonky.Client.HttpRepository;
|
||||
using Wonky.Client.Local.Services;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
|
@ -30,13 +32,15 @@ public partial class AdvisorCustomerActivityListPage : IDisposable
|
|||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] public ICrmActivityRepository CrmActivityRepo { get; set; }
|
||||
[Inject] public ICrmCustomerRepository CompanyRepo { get; set; }
|
||||
[Inject] public IDrawerCabinetService CabinetService { get; set; }
|
||||
[Inject] public ILogger<AdvisorCustomerActivityListPage> Logger { get; set; }
|
||||
|
||||
// ######################################################################
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
|
||||
// ######################################################################
|
||||
private List<ReportItemView> ActivityList { get; set; } = new();
|
||||
private CompanyDto Company { get; set; } = new();
|
||||
private List<ReportItemView> Activities { get; set; } = new();
|
||||
private bool Working { get; set; } = true;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
|
@ -53,9 +57,14 @@ public partial class AdvisorCustomerActivityListPage : IDisposable
|
|||
|
||||
private async Task GetActivities()
|
||||
{
|
||||
ActivityList = await CrmActivityRepo.GetCustomerActivities(CompanyId);
|
||||
if (ActivityList.Any())
|
||||
ActivityList = ActivityList.OrderByDescending(x => x.OrderDate).ToList();
|
||||
Activities = new List<ReportItemView>();
|
||||
var drawer = await CabinetService.GetActivityDrawerAsync(CompanyId);
|
||||
if (drawer.Content.Any())
|
||||
{
|
||||
Activities = drawer.Content
|
||||
.OrderByDescending(x => x.OrderDate)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
@ -23,6 +23,7 @@ using Wonky.Client.Enums;
|
|||
using Wonky.Client.Helpers;
|
||||
using Wonky.Client.HttpInterceptors;
|
||||
using Wonky.Client.HttpRepository;
|
||||
using Wonky.Client.Local.Services;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Client.OverlayCustomer;
|
||||
using Wonky.Client.Shared;
|
||||
|
@ -34,6 +35,7 @@ namespace Wonky.Client.Pages;
|
|||
|
||||
public partial class AdvisorCustomerInventoryListPage : IDisposable
|
||||
{
|
||||
// ##############################################################
|
||||
[Inject] public ICrmCustomerHistoryRepository HistoryRepo { get; set; }
|
||||
[Inject] public ICrmCustomerRepository CustomerRepo { get; set; }
|
||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||
|
@ -41,11 +43,13 @@ public partial class AdvisorCustomerInventoryListPage : IDisposable
|
|||
[Inject] public ILogger<AdvisorCustomerInventoryListPage> Logger { get; set; }
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] public ICountryCatalogRepository CatalogRepo { get; set; }
|
||||
[Inject] public IDrawerCabinetService CabinetService { get; set; }
|
||||
|
||||
// ##############################################################
|
||||
[CascadingParameter] public DraftStateProvider DraftStateProvider { get; set; } = new();
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
|
||||
|
||||
// ##############################################################
|
||||
private readonly JsonSerializerOptions _options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
|
||||
private CompanyDto Company { get; set; } = new();
|
||||
private bool Working { get; set; } = true;
|
||||
|
@ -53,14 +57,14 @@ public partial class AdvisorCustomerInventoryListPage : IDisposable
|
|||
private CustomerInventoryReorderOverlay ReorderOverlay { get; set; } = new();
|
||||
private List<ProductInventoryItemView> Inventory { get; set; } = new();
|
||||
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
|
||||
Interceptor.RegisterEvent();
|
||||
Interceptor.RegisterBeforeSendEvent();
|
||||
|
||||
Company = await CustomerRepo.GetCompanyById(CompanyId);
|
||||
var drawer = await CabinetService.GetInfoDrawerAsync(CompanyId);
|
||||
Company = drawer.Content;
|
||||
|
||||
// fetch product inventory
|
||||
await FetchProductInventory();
|
||||
|
@ -89,11 +93,11 @@ public partial class AdvisorCustomerInventoryListPage : IDisposable
|
|||
|
||||
private async Task FetchProductInventory()
|
||||
{
|
||||
Inventory = new List<ProductInventoryItemView>();
|
||||
Inventory = await HistoryRepo.FetchInventory(CompanyId);
|
||||
if (Inventory.Any())
|
||||
Inventory = Inventory.OrderBy(x => x.Description).ToList();
|
||||
|
||||
var drawer = await CabinetService.GetInventoryDrawerAsync(CompanyId);
|
||||
if (drawer.Content.Any())
|
||||
{
|
||||
Inventory = drawer.Content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -18,26 +18,26 @@
|
|||
@using Wonky.Client.OverlayCustomer
|
||||
@page "/advisor/customers/{CompanyId}/invoices"
|
||||
@attribute [Authorize(Roles = "Advisor")]
|
||||
<PageTitle>Faktura Oversigt for @Company.Name</PageTitle>
|
||||
@if (!string.IsNullOrWhiteSpace(Company.Name))
|
||||
<PageTitle>Faktura Oversigt for @_company.Name</PageTitle>
|
||||
@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>
|
||||
<h4 class="pt-1">@_company.Name</h4>
|
||||
</div>
|
||||
<div class="col-sm-3 align-content-end">
|
||||
<a class="btn btn-primary d-block" href="/advisor/customers/@Company.CompanyId"><i class="bi-chevron-left"></i> Stamkort</a>
|
||||
<a class="btn btn-primary d-block" href="/advisor/customers/@_company.CompanyId"><i class="bi-chevron-left"></i> Stamkort</a>
|
||||
</div>
|
||||
<div class="col-sm-3 align-content-end">
|
||||
<a class="btn btn-primary d-block" href="/advisor/customers/@Company.CompanyId/activities/new"><i class="bi-chevron-right"></i> Besøg</a>
|
||||
<a class="btn btn-primary d-block" href="/advisor/customers/@_company.CompanyId/activities/new"><i class="bi-chevron-right"></i> Besøg</a>
|
||||
</div>
|
||||
</div>
|
||||
<CustomerInvoiceListComponent OnShowInvoice="CallInvoiceModal" CompanyId="@CompanyId" InvoiceList="@CompanyInvoices.Invoices"/>
|
||||
<CustomerInvoiceListComponent OnShowInvoice="ShowInvoiceModal" Invoices="@_invoiceDrawer.Content"/>
|
||||
}
|
||||
|
||||
@if (Working)
|
||||
@if (_working)
|
||||
{
|
||||
<WorkingThreeDots />
|
||||
}
|
||||
|
||||
<CustomerInvoiceViewOverlay CompanyId="@CompanyId" InvoiceId="@InvoiceId" @ref="CustomerInvoiceView" />
|
||||
<CustomerInvoiceViewOverlay CompanyId="@CompanyId" InvoiceId="@_invoiceId" @ref="CustomerInvoiceView" />
|
|
@ -19,6 +19,8 @@ using Blazored.Toast.Services;
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Wonky.Client.HttpInterceptors;
|
||||
using Wonky.Client.HttpRepository;
|
||||
using Wonky.Client.Local.Services;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Client.OverlayCustomer;
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Views;
|
||||
|
@ -28,87 +30,46 @@ namespace Wonky.Client.Pages;
|
|||
|
||||
public partial class AdvisorCustomerInvoiceListPage : IDisposable
|
||||
{
|
||||
// ##############################################################
|
||||
[Inject] public ILogger<AdvisorCustomerInvoiceListPage> Logger { get; set; }
|
||||
[Inject] public ICrmCustomerRepository CompanyRepo { get; set; }
|
||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] public ICrmCustomerHistoryRepository HistoryRepo { get; set; }
|
||||
[Inject] public IToastService Toaster { get; set; }
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] public ILogger<AdvisorCustomerInvoiceListPage> Logger { get; set; }
|
||||
[Inject] public IDrawerCabinetService CabinetService { get; set; }
|
||||
|
||||
// ##############################################################
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
|
||||
private InvoiceListView CompanyInvoices { get; set; } = new();
|
||||
private CompanyDto Company { get; set; } = new();
|
||||
// ##############################################################
|
||||
private CustomerInvoiceViewOverlay CustomerInvoiceView { get; set; } = new();
|
||||
private string InvoiceId { get; set; } = "";
|
||||
private bool Working { get; set; }
|
||||
private bool AllSet { get; set; }
|
||||
private string _companyId = "";
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_companyId = CompanyId;
|
||||
Working = true;
|
||||
}
|
||||
private string _invoiceId = "";
|
||||
private bool _working = true;
|
||||
private CompanyDto _company = new();
|
||||
private InvoiceDrawer _invoiceDrawer = new();
|
||||
private InfoDrawer _infoDrawer = new();
|
||||
private List<InvoiceListItemView> _invoices = new();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Interceptor.RegisterEvent();
|
||||
Interceptor.RegisterBeforeSendEvent();
|
||||
|
||||
Company = await CompanyRepo.GetCompanyById(_companyId);
|
||||
_infoDrawer = await CabinetService.GetInfoDrawerAsync(CompanyId);
|
||||
_invoiceDrawer = await CabinetService.GetInvoiceDrawerAsync(CompanyId);
|
||||
_company = _infoDrawer.Content;
|
||||
_invoices = _invoiceDrawer.Content;
|
||||
|
||||
// while (string.IsNullOrWhiteSpace(Company.HistorySync))
|
||||
// await Task.Delay(500);
|
||||
//
|
||||
// var iDate = await Storage.GetItemAsStringAsync($"{_companyId}-iDate");
|
||||
// if (string.IsNullOrWhiteSpace(iDate) || (iDate == Company.HistorySync && iDate != $"{DateTime.Now:yyyy-MM-dd}"))
|
||||
// {
|
||||
// // send rpc to sync invoices from ERP to CRM
|
||||
// var ts = await HistoryRepo.ErpInvoiceToCrmRpc(_companyId, Company.HistorySync);
|
||||
// // wait until we have the result
|
||||
// while (string.IsNullOrWhiteSpace(ts))
|
||||
// await Task.Delay(500);
|
||||
//
|
||||
// await Storage.SetItemAsync($"{_companyId}-iDate", ts);
|
||||
// }
|
||||
CompanyInvoices = await FetchCompanyInvoices();
|
||||
AllSet = true;
|
||||
_working = false;
|
||||
}
|
||||
|
||||
private void CallInvoiceModal(string invoiceId)
|
||||
|
||||
private void ShowInvoiceModal(string invoiceId)
|
||||
{
|
||||
InvoiceId = invoiceId;
|
||||
_invoiceId = invoiceId;
|
||||
CustomerInvoiceView.Show();
|
||||
}
|
||||
|
||||
private async Task<InvoiceListView> FetchCompanyInvoices()
|
||||
{
|
||||
// fetch from storage
|
||||
var storage = await Storage.GetItemAsStringAsync($"{_companyId}-invoices");
|
||||
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");
|
||||
return JsonSerializer.Deserialize<InvoiceListView>(storage);
|
||||
}
|
||||
Logger.LogDebug("pulling invoices from backend");
|
||||
// pull invoices
|
||||
var companyInvoices = await HistoryRepo.FetchInvoiceList(_companyId);
|
||||
if (companyInvoices.Invoices.Any())
|
||||
companyInvoices.Invoices = companyInvoices.Invoices
|
||||
.OrderByDescending(x => x.DocumentDate)
|
||||
.ToList();
|
||||
|
||||
// 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;
|
||||
return companyInvoices;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
|
|
@ -17,28 +17,28 @@
|
|||
@using Wonky.Client.Components
|
||||
@attribute [Authorize(Roles = "Advisor")]
|
||||
@page "/advisor/customers/{CompanyId}"
|
||||
<PageTitle>Stamkort for @Company.Name</PageTitle>
|
||||
<PageTitle>Stamkort for @_infoDrawer.Content.Name</PageTitle>
|
||||
|
||||
@if (!string.IsNullOrWhiteSpace(Company.Account))
|
||||
@if (!string.IsNullOrWhiteSpace(_infoDrawer.Content.Account))
|
||||
{
|
||||
@if (!string.IsNullOrWhiteSpace(Company.Blocked))
|
||||
@if (!string.IsNullOrWhiteSpace(_infoDrawer.Content.Blocked))
|
||||
{
|
||||
<div class="alert alert-danger">
|
||||
<h4>Ring til kontoret. Denne konto er spærret med kode '@Company.Blocked'</h4>
|
||||
<h4>Ring til kontoret. Denne konto er spærret med kode '@_infoDrawer.Content.Blocked'</h4>
|
||||
</div>
|
||||
}
|
||||
<div class="row pt-2 pb-2 mb-2 rounded rounded-2 bg-dark text-white">
|
||||
<div class="col-sm-7">
|
||||
<div class="mt-1">
|
||||
<span class="h3">@Company.Name</span> <span>(@Company.Account)</span>
|
||||
<span class="h3">@_infoDrawer.Content.Name</span> <span>(@_infoDrawer.Content.Account)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5 text-end">
|
||||
@if (UserInfo.CountryCode is "DK")
|
||||
@if (_userInfo.CountryCode is "DK")
|
||||
{
|
||||
<a class="btn btn-secondary me-2" href="/advisor/customers/@CompanyId/workplaces/new"><i class="bi-plus-lg"></i> Arbejdssted</a>
|
||||
}
|
||||
@* <button class="btn btn-secondary me-2" @onclick="@ConfirmReloadHistory" disabled="@Working"><i class="bi-recycle"></i> Varelinjer</button> *@
|
||||
<button class="btn btn-secondary me-2" @onclick="@ReloadHistory" disabled="@Working"><i class="bi-repeat"></i> Historik</button>
|
||||
<a class="btn btn-primary me-2" href="/advisor/customers"><i class="bi-chevron-left"></i> Tilbage</a>
|
||||
</div>
|
||||
|
||||
|
@ -50,78 +50,78 @@
|
|||
@* Company Name *@
|
||||
<label for="name" class="col-sm-1 col-form-label-sm">Navn</label>
|
||||
<div class="col-sm-5">
|
||||
<InputText id="name" class="form-control" @bind-Value="Company.Name" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => Company.Name)"></ValidationMessage>
|
||||
<InputText id="name" class="form-control" @bind-Value="_infoDrawer.Content.Name" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.Name)"></ValidationMessage>
|
||||
</div>
|
||||
@* Company Attention *@
|
||||
<label for="attention" class="col-sm-1 col-form-label-sm">Att.</label>
|
||||
<div class="col-sm-5">
|
||||
<InputText id="attention" class="form-control" @bind-Value="Company.Attention" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => Company.Attention)"></ValidationMessage>
|
||||
<InputText id="attention" class="form-control" @bind-Value="_infoDrawer.Content.Attention" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.Attention)"></ValidationMessage>
|
||||
</div>
|
||||
@* Address 1 *@
|
||||
<label for="address1" class="col-sm-1 col-form-label-sm">Adresse</label>
|
||||
<div class="col-sm-5">
|
||||
<InputText id="address1" class="form-control" @bind-Value="Company.Address1" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => Company.Address1)"></ValidationMessage>
|
||||
<InputText id="address1" class="form-control" @bind-Value="_infoDrawer.Content.Address1" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.Address1)"></ValidationMessage>
|
||||
</div>
|
||||
@* Address 2 *@
|
||||
<label for="address2" class="col-sm-1 col-form-label-sm">Adresse</label>
|
||||
<div class="col-sm-5">
|
||||
<InputText id="address2" class="form-control" @bind-Value="Company.Address2" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => Company.Address2)"></ValidationMessage>
|
||||
<InputText id="address2" class="form-control" @bind-Value="_infoDrawer.Content.Address2" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.Address2)"></ValidationMessage>
|
||||
</div>
|
||||
@* Post Code *@
|
||||
<label for="zipCode" class="col-sm-1 col-form-label-sm">PostNr</label>
|
||||
<div class="col-sm-1">
|
||||
<InputText id="zipCode" class="form-control" @bind-Value="Company.ZipCode" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => Company.ZipCode)"></ValidationMessage>
|
||||
<InputText id="zipCode" class="form-control" @bind-Value="_infoDrawer.Content.ZipCode" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.ZipCode)"></ValidationMessage>
|
||||
</div>
|
||||
@* City Name *@
|
||||
<label for="city" class="col-sm-1 col-form-label-sm">Bynavn</label>
|
||||
<div class="col-sm-3">
|
||||
<InputText id="city" class="form-control" @bind-Value="Company.City" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => Company.City)"></ValidationMessage>
|
||||
<InputText id="city" class="form-control" @bind-Value="_infoDrawer.Content.City" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.City)"></ValidationMessage>
|
||||
</div>
|
||||
@* Email *@
|
||||
<label for="email" class="col-sm-1 col-form-label-sm">Epost</label>
|
||||
<div class="col-sm-5">
|
||||
<InputText id="email" class="form-control" @bind-Value="Company.Email" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => Company.Email)"></ValidationMessage>
|
||||
<InputText id="email" class="form-control" @bind-Value="_infoDrawer.Content.Email" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.Email)"></ValidationMessage>
|
||||
</div>
|
||||
@* Phone *@
|
||||
<label for="phone" class="col-sm-1 col-form-label-sm">Telefon</label>
|
||||
<div class="col-sm-2">
|
||||
<InputText id="phone" class="form-control" @bind-Value="Company.Phone" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => Company.Phone)"></ValidationMessage>
|
||||
<InputText id="phone" class="form-control" @bind-Value="_infoDrawer.Content.Phone" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.Phone)"></ValidationMessage>
|
||||
</div>
|
||||
@* Mobile *@
|
||||
<label for="mobile" class="col-sm-1 col-form-label-sm">Mobil</label>
|
||||
<div class="col-sm-2">
|
||||
<InputText id="mobile" class="form-control" @bind-Value="Company.Mobile" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => Company.Mobile)"></ValidationMessage>
|
||||
<InputText id="mobile" class="form-control" @bind-Value="_infoDrawer.Content.Mobile" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.Mobile)"></ValidationMessage>
|
||||
</div>
|
||||
@* Email *@
|
||||
<label for="eanNumber" class="col-sm-1 col-form-label-sm">EAN</label>
|
||||
<div class="col-sm-5">
|
||||
<InputText id="eanNumber" class="form-control" @bind-Value="Company.EanNumber" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => Company.EanNumber)"></ValidationMessage>
|
||||
<InputText id="eanNumber" class="form-control" @bind-Value="_infoDrawer.Content.EanNumber" readonly="@(ErpEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.EanNumber)"></ValidationMessage>
|
||||
</div>
|
||||
|
||||
@if (!Kanvas)
|
||||
{
|
||||
@* entity segment *@
|
||||
@if (UserInfo.CountryCode.ToLower() == "dk")
|
||||
@if (_userInfo.CountryCode.ToLower() == "dk")
|
||||
{
|
||||
<label for="segment" class="col-sm-1 col-form-label-sm">Segment</label>
|
||||
<div class="col-sm-2">
|
||||
<InputSelect id="segment" class="form-select bg-warning text-bg-warning"
|
||||
@bind-Value="@Company.Segment" disabled="@(ErpEditDisabled)">
|
||||
@bind-Value="@_infoDrawer.Content.Segment" disabled="@(ErpEditDisabled)">
|
||||
<option value="" disabled>segment</option>
|
||||
<option value="1">AUTO</option>
|
||||
<option value="2">INDUSTRI</option>
|
||||
</InputSelect>
|
||||
<ValidationMessage For="@(() => Company.Segment)"></ValidationMessage>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.Segment)"></ValidationMessage>
|
||||
</div>
|
||||
<div class="col-sm-1">
|
||||
<div class="led-box @(DateTime.Now < DateTime.Parse("2023-12-31") ? "inno-display" : "inno-hidden")">
|
||||
|
@ -145,7 +145,7 @@
|
|||
</div>
|
||||
@* Save erp data *@
|
||||
<div class="col-sm-3 d-grid mx-auto">
|
||||
<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>
|
||||
<button type="button" class="btn btn-danger d-block" @onclick="@UpdateErpData" disabled="@(Working || _infoDrawer.Content.Name == "ERROR" || ErpEditDisabled)"><i class="bi-cloud-arrow-up"></i> STAM data </button>
|
||||
</div>
|
||||
@* vat number*@
|
||||
<hr class="mb-3"/>
|
||||
|
@ -155,8 +155,8 @@
|
|||
<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>
|
||||
<InputText id="vatNumber" class="form-control" @bind-Value="_infoDrawer.Content.VatNumber" readonly="@(VatEditDisabled)"/>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.VatNumber)"></ValidationMessage>
|
||||
</div>
|
||||
</div>
|
||||
@* Enable edit/save vatnumber *@
|
||||
|
@ -174,7 +174,7 @@
|
|||
<a class="btn btn-info" href="https://brreg.no/" target="_blank"><i class="bi-search"></i> brreg.no</a>
|
||||
break;
|
||||
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/@_infoDrawer.Content.Name" target="_blank"><i class="bi-search"></i> allabolag.se</a>
|
||||
break;
|
||||
}
|
||||
</div>
|
||||
|
@ -232,19 +232,19 @@
|
|||
<div class="row mb-2">
|
||||
<label for="note" class="col-sm-1 col-form-label-sm">OBS</label>
|
||||
<div class="col-sm-8">
|
||||
@if (string.IsNullOrWhiteSpace(Company.Note))
|
||||
@if (string.IsNullOrWhiteSpace(_infoDrawer.Content.Note))
|
||||
{
|
||||
<InputText name="note" id="note" class="form-control" @bind-Value="Company.Note"/>
|
||||
<InputText name="note" id="note" class="form-control" @bind-Value="_infoDrawer.Content.Note"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
<InputText name="note" id="note" class="form-control bg-warning text-black" @bind-Value="Company.Note"/>
|
||||
<InputText name="note" id="note" class="form-control bg-warning text-black" @bind-Value="_infoDrawer.Content.Note"/>
|
||||
}
|
||||
<ValidationMessage For="@(() => Company.Note)"></ValidationMessage>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.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>
|
||||
<button type="button" class="btn btn-warning" disabled="@(_infoDrawer.Content.Name == "ERROR")" @onclick="@PostCrmData"><i class="bi-cloud-arrow-up"></i> CRM data</button>
|
||||
</div>
|
||||
</div>
|
||||
@* crm context - contacts *@
|
||||
|
@ -300,14 +300,14 @@
|
|||
</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>
|
||||
<InputNumber id="interval" class="form-control" @bind-Value="_infoDrawer.Content.Interval"/>
|
||||
<ValidationMessage For="@(() => _infoDrawer.Content.Interval)"></ValidationMessage>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<label for="crmNotes" class="col-sm-1 col-form-label-sm">Noter</label>
|
||||
<div class="col-sm-11">
|
||||
<InputTextArea id="crmNotes" class="form-control" @bind-Value="Company.CrmNotes"/>
|
||||
<InputTextArea id="crmNotes" class="form-control" @bind-Value="_infoDrawer.Content.CrmNotes"/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -318,7 +318,7 @@
|
|||
<button type="button" class="btn btn-outline-dark" @onclick="@ToggleVisibility">@ToggleButtonText</button>
|
||||
</div>
|
||||
<div class="col-sm-4 d-grid">
|
||||
@if (UserInfo.CountryCode is "DK")
|
||||
@if (_userInfo.CountryCode is "DK")
|
||||
{
|
||||
<a class="btn btn-info" href="@($"/advisor/customers/{CompanyId}/workplaces")">Kemi Dokumentation</a>
|
||||
}
|
||||
|
@ -331,10 +331,8 @@
|
|||
<WorkingThreeDots/>
|
||||
}
|
||||
|
||||
<VatLookupDkModal VatAddress="CompanyVatAddress" EntityName="@Company.Name" VatNumber="@Company.VatNumber"
|
||||
<VatLookupDkModal VatAddress="CompanyVatAddress" EntityName="@_infoDrawer.Content.Name" VatNumber="@_infoDrawer.Content.VatNumber"
|
||||
@ref="VatLookupPopup" OnSelectedCompany="SelectedCompanyCallback"/>
|
||||
|
||||
<ContactViewEditModal SelectedContact="SelectedContact" CompanyName="@Company.Name"
|
||||
<ContactViewEditModal SelectedContact="SelectedContact" CompanyName="@_infoDrawer.Content.Name"
|
||||
@ref="ContactViewPopup" OnSaveClicked="WriteContactCallback" OnDeleteClicked="DeleteContactCallback"/>
|
||||
|
||||
<ConfirmActionModal BodyMessage="@RemoveHistoryWarning" OnOkClicked="ReloadHistory" @ref="ConfirmActionHistory" />
|
|
@ -14,7 +14,6 @@
|
|||
//
|
||||
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using Blazored.LocalStorage;
|
||||
using Blazored.Toast.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
@ -40,25 +39,32 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
|||
[Inject] public IToastService Toaster { get; set; }
|
||||
[Inject] public ILogger<AdvisorCustomerViewEditPage> Logger { get; set; }
|
||||
[Inject] public NavigationManager Navigator { get; set; }
|
||||
[Inject] public ICrmActivityRepository ActivityRepo { get; set; }
|
||||
[Inject] public ICrmCustomerRepository CustomerRepo { get; set; }
|
||||
[Inject] public ICrmCustomerHistoryRepository HistoryRepo { get; set; }
|
||||
[Inject] public ICrmContactRepository CrmContactRepo { get; set; }
|
||||
[Inject] public ICrmContactRepository ContactRepo { get; set; }
|
||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] public VatInfoLookupService VatService { get; set; }
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] public IUserInfoService UserInfoService { get; set; }
|
||||
[Inject] public IOptions<AppInfo?>? AppInfo { get; set; }
|
||||
[Inject] public IDrawerCabinetService CabinetService { get; set; }
|
||||
|
||||
// ###########################################################################
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
|
||||
// ###########################################################################
|
||||
private readonly JsonSerializerOptions _options = new() { PropertyNameCaseInsensitive = true };
|
||||
private CompanyDto Company { get; set; } = new();
|
||||
private EditContext ErpContext { get; set; }
|
||||
private DateTime LastVisit { get; set; }
|
||||
private DateTime NextVisit { get; set; }
|
||||
private VatAddress CompanyVatAddress { get; set; } = new();
|
||||
private ContactDto SelectedContact { get; set; } = new();
|
||||
private ContactDto DefaultContact { get; set; } = new();
|
||||
private ContactViewEditModal ContactViewPopup { get; set; } = new();
|
||||
private VatLookupDkModal VatLookupPopup { get; set; } = new();
|
||||
private List<ContactDto> Contacts { get; set; } = new();
|
||||
private UserManagerEditView _userInfo = new();
|
||||
private InfoDrawer _infoDrawer = new();
|
||||
private string VatState { get; set; } = "the-ugly";
|
||||
private bool ValidVat { get; set; }
|
||||
private bool HasFolded { get; set; }
|
||||
|
@ -70,119 +76,168 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
|||
private bool CountryIsDk { get; set; } = true;
|
||||
private bool ErpEditDisabled { get; set; } = true;
|
||||
private bool VatEditDisabled { get; set; } = true;
|
||||
private List<ContactDto> Contacts { get; set; } = new();
|
||||
private UserManagerEditView UserInfo { get; set; } = new();
|
||||
private string ToggleButtonText { get; set; } = "";
|
||||
private bool Kanvas { get; set; }
|
||||
private ContactDto SelectedContact { get; set; } = new();
|
||||
private ContactDto DefaultContact { get; set; } = new();
|
||||
private ContactViewEditModal ContactViewPopup { get; set; } = new();
|
||||
private VatLookupDkModal VatLookupPopup { get; set; } = new();
|
||||
private string RemoveHistoryWarning { get; set; } = "";
|
||||
private ConfirmActionModal ConfirmActionHistory { get; set; }
|
||||
private string InventoryLink { get; set; } = "";
|
||||
private string ActivityLink { get; set; } = "";
|
||||
private string InvoiceLink { get; set; } = "";
|
||||
private string NewActivityLink { get; set; } = "";
|
||||
private int EnableLink { get; set; } = 1;
|
||||
|
||||
private ActivityDrawer _activityDrawer = new();
|
||||
private InventoryDrawer _inventoryDrawer = new();
|
||||
private InvoiceDrawer _invoiceDrawer = new();
|
||||
private StatisticDrawer _statisticDrawer = new();
|
||||
private string _companyId = "";
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// setup interceptor
|
||||
/*
|
||||
* setup interceptor
|
||||
*/
|
||||
Interceptor.RegisterEvent();
|
||||
Interceptor.RegisterBeforeSendEvent();
|
||||
|
||||
// initialize default contact
|
||||
/*
|
||||
* default contact
|
||||
*/
|
||||
DefaultContact = new ContactDto { CompanyId = CompanyId, ContactId = "", FirstName = "" };
|
||||
|
||||
// navigation button links
|
||||
/*
|
||||
* navigation button links
|
||||
*/
|
||||
InventoryLink = $"/advisor/customers/{CompanyId}/history/inventory";
|
||||
ActivityLink = $"/advisor/customers/{CompanyId}/activities";
|
||||
InvoiceLink = $"/advisor/customers/{CompanyId}/invoices";
|
||||
NewActivityLink = $"/advisor/customers/{CompanyId}/activities/new";
|
||||
|
||||
// setup form context
|
||||
ErpContext = new EditContext(Company);
|
||||
|
||||
// assign event handlers to context
|
||||
/*
|
||||
* setup form context
|
||||
*/
|
||||
ErpContext = new EditContext(_infoDrawer.Content);
|
||||
/*
|
||||
* assign event handlers to context
|
||||
*/
|
||||
ErpContext.OnFieldChanged += HandleFieldChanged;
|
||||
ErpContext.OnValidationStateChanged += ValidationChanged!;
|
||||
|
||||
// fetch user info from local storage
|
||||
UserInfo = await UserInfoService.GetUserInfo();
|
||||
CountryCode = UserInfo.CountryCode.ToLower();
|
||||
/*
|
||||
* fetch user info from local storage
|
||||
*/
|
||||
_userInfo = await UserInfoService.GetUserInfo();
|
||||
CountryCode = _userInfo.CountryCode.ToLower();
|
||||
CountryIsDk = CountryCode == "dk";
|
||||
|
||||
Logger.LogDebug("companyId => {}", CompanyId);
|
||||
|
||||
Company = await CustomerRepo.GetCompanyById(CompanyId);
|
||||
|
||||
// internal flag
|
||||
EnableActivity = Company.ValidVat;
|
||||
// override if canvas which has account property as empty string or "NY"
|
||||
if (Company.Account.StartsWith("NY") || Company.Account.StartsWith("KANVAS") || string.IsNullOrWhiteSpace(Company.Account))
|
||||
/*
|
||||
* get InfoDrawer.Company from drawer
|
||||
*/
|
||||
_infoDrawer = await CabinetService.GetInfoDrawerAsync(CompanyId);
|
||||
_infoDrawer.Content = _infoDrawer.Content;
|
||||
/*
|
||||
* internal EnableActivity flag
|
||||
*/
|
||||
EnableActivity = _infoDrawer.Content.ValidVat;
|
||||
/*
|
||||
* if KANVAS or NY override EnableActivity
|
||||
*/
|
||||
if (_infoDrawer.Content.Account.StartsWith("NY") || _infoDrawer.Content.Account.StartsWith("KANVAS") || string.IsNullOrWhiteSpace(_infoDrawer.Content.Account))
|
||||
EnableActivity = 1;
|
||||
|
||||
if (Company.Account.StartsWith("KANVAS"))
|
||||
if (_infoDrawer.Content.Account.StartsWith("KANVAS"))
|
||||
Kanvas = true;
|
||||
|
||||
// only execute if the company a 'real' customer
|
||||
/*
|
||||
* only execute if the InfoDrawer.Company is not KANVAS
|
||||
*/
|
||||
if (!Kanvas)
|
||||
{
|
||||
Logger.LogDebug("company => {}", JsonSerializer.Serialize(Company));
|
||||
// toggle view button text
|
||||
ToggleButtonText = Company.IsHidden == 0 ? "Udelad kunde i oversigt" : "Brug Normal Visning";
|
||||
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
|
||||
Logger.LogDebug("InfoDrawer.Company => {}", JsonSerializer.Serialize(_infoDrawer.Content));
|
||||
/*
|
||||
* toggle view button text
|
||||
*/
|
||||
ToggleButtonText = _infoDrawer.Content.IsHidden == 0 ? "Udelad kunde i oversigt" : "Brug Normal Visning";
|
||||
CurrentVat = _infoDrawer.Content.VatNumber;
|
||||
_infoDrawer.Content.CountryCode = _userInfo.CountryCode.ToLower();
|
||||
/*
|
||||
* visit interval init
|
||||
*/
|
||||
if (_infoDrawer.Content.Interval == 0)
|
||||
_infoDrawer.Content.Interval = 8;
|
||||
/*
|
||||
* visit date init
|
||||
*/
|
||||
LastVisit = DateTime.Parse(_infoDrawer.Content.LastVisit);
|
||||
NextVisit = DateTime.Parse(_infoDrawer.Content.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
|
||||
/*
|
||||
* set next visit according to last visit and interval
|
||||
*/
|
||||
if (!_infoDrawer.Content.ValidDateSpan())
|
||||
NextVisit = LastVisit.AddDays(_infoDrawer.Content.Interval * 7);
|
||||
/*
|
||||
* display urgency of next visit
|
||||
*/
|
||||
VisitState = Utils.GetVisitState($"{NextVisit:yyyy-MM-dd}");
|
||||
// handle company out of business case
|
||||
if (Company.HasFolded == 1)
|
||||
/*
|
||||
* handle InfoDrawer.Company out of business case
|
||||
*/
|
||||
if (_infoDrawer.Content.HasFolded == 1)
|
||||
{
|
||||
// this is only used if user has selected to show closed companies
|
||||
/*
|
||||
* 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
|
||||
/*
|
||||
* vat validation flags
|
||||
*/
|
||||
_infoDrawer.Content.ValidVat = VatUtils.ValidateFormat(_infoDrawer.Content.CountryCode, _infoDrawer.Content.VatNumber) ? 1 : 0;
|
||||
ValidVat = _infoDrawer.Content.ValidVat == 1; // true/false flag set if InfoDrawer.Company has a valid vatNumber
|
||||
VatState = _infoDrawer.Content.ValidVat == 1 ? "the-good" : "no-vat"; // assign css class
|
||||
}
|
||||
|
||||
// create search address from address
|
||||
/*
|
||||
* create search address from address
|
||||
*/
|
||||
if (CountryIsDk)
|
||||
{
|
||||
CompanyVatAddress = PrepareVatAddress(Company);
|
||||
CompanyVatAddress = PrepareVatAddress(_infoDrawer.Content);
|
||||
}
|
||||
|
||||
await FetchContacts(CompanyId);
|
||||
|
||||
Working = false;
|
||||
|
||||
await RequestErpUpdate();
|
||||
await GetContacts(CompanyId);
|
||||
}
|
||||
|
||||
// remove loading image
|
||||
/*
|
||||
* remove loading image
|
||||
*/
|
||||
Working = false;
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_companyId))
|
||||
{
|
||||
_companyId = CompanyId;
|
||||
await CabinetService.GetInvoiceDrawerAsync(CompanyId, true);
|
||||
await CabinetService.GetInventoryDrawerAsync(CompanyId, true);
|
||||
await CabinetService.GetActivityDrawerAsync(CompanyId, true);
|
||||
await CabinetService.GetStatisticDrawerAsync(CompanyId, true);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ReloadHistory()
|
||||
{
|
||||
Toaster.ShowWarning("Arbejder på sagen ...");
|
||||
var newSync = await HistoryRepo.RequestErpSync(CompanyId, _infoDrawer.Content.HistorySync, false);
|
||||
if (!string.IsNullOrWhiteSpace(newSync))
|
||||
{
|
||||
_infoDrawer.Content.HistorySync = newSync;
|
||||
_infoDrawer.Content = _infoDrawer.Content;
|
||||
await CabinetService.StoreInfoDrawerAsync(CompanyId, _infoDrawer);
|
||||
}
|
||||
await CabinetService.GetInvoiceDrawerAsync(CompanyId, true);
|
||||
await CabinetService.GetInventoryDrawerAsync(CompanyId, true);
|
||||
await CabinetService.GetActivityDrawerAsync(CompanyId, true);
|
||||
await CabinetService.GetStatisticDrawerAsync(CompanyId, true);
|
||||
|
||||
Toaster.ShowSuccess("Data er snart klar ....");
|
||||
}
|
||||
|
||||
private void ToggleErpEdit()
|
||||
{
|
||||
|
@ -196,61 +251,31 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
|||
}
|
||||
|
||||
|
||||
private void ConfirmReloadHistory()
|
||||
{
|
||||
// $"Bekræft at du sletter<br/><strong>{Workplace.Name}</strong> fra <strong>{Workplace.CompanyName}</strong>?<br/>AL INFORMATION slettes og handlingen er uigenkaldelig.";
|
||||
RemoveHistoryWarning = $"Denne process kan tage lang tid.<br/>Bekræft at al historik gendannes for<br/>{Company.Account} {Company.Name}";
|
||||
ConfirmActionHistory.Show();
|
||||
}
|
||||
|
||||
|
||||
private async Task ReloadHistory()
|
||||
{
|
||||
if (Working)
|
||||
return;
|
||||
Toaster.ShowWarning("Vent venligst ....");
|
||||
Working = true;
|
||||
EnableLink = 0;
|
||||
EnableActivity = 0;
|
||||
var result = await HistoryRepo.GetRecycledInvoiceList(CompanyId, Company.HistorySync, true);
|
||||
await Task.Delay(1000);
|
||||
Working = false;
|
||||
if (!string.IsNullOrWhiteSpace(result))
|
||||
{
|
||||
Toaster.ShowInfo("Historik gendannelse er færdig");
|
||||
EnableLink = 1;
|
||||
EnableActivity = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task ToggleVisibility()
|
||||
{
|
||||
Company.IsHidden = Company.IsHidden == 0 ? 1 : 0;
|
||||
// toggle view button text
|
||||
ToggleButtonText = Company.IsHidden == 0 ? "Udelad kunde i oversigt" : "Brug Normal Visning";
|
||||
Logger.LogDebug("ToggleVisibility => Company.IsHidden == {}", Company.IsHidden);
|
||||
await CustomerRepo.UpdateCrmData(CompanyId, Company);
|
||||
/*
|
||||
* toggle view button text
|
||||
*/
|
||||
_infoDrawer.Content.IsHidden = _infoDrawer.Content.IsHidden == 0 ? 1 : 0;
|
||||
ToggleButtonText = _infoDrawer.Content.IsHidden == 0 ? "Udelad kunde i oversigt" : "Brug Normal Visning";
|
||||
/*
|
||||
* send update reqeust
|
||||
*/
|
||||
await CustomerRepo.UpdateCrmData(CompanyId, _infoDrawer.Content);
|
||||
}
|
||||
|
||||
|
||||
private async Task RequestErpUpdate()
|
||||
private async Task GetContacts(string companyId)
|
||||
{
|
||||
if (Working)
|
||||
return;
|
||||
Working = true;
|
||||
Company.HistorySync = await HistoryRepo.GetRecycledInvoiceList(CompanyId, Company.HistorySync, false);
|
||||
Working = false;
|
||||
}
|
||||
|
||||
|
||||
private async Task FetchContacts(string companyId)
|
||||
{
|
||||
// load contacts
|
||||
Contacts = await CrmContactRepo.GetContacts(companyId);
|
||||
/*
|
||||
* load contacts
|
||||
*/
|
||||
Contacts = await ContactRepo.GetContacts(companyId);
|
||||
if (Contacts.Any() && Contacts.Count > 1)
|
||||
{
|
||||
Contacts = Contacts.OrderBy(x => x.FirstName).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void OpenVatLookupModal()
|
||||
|
@ -261,83 +286,95 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
|||
|
||||
private void SelectedCompanyCallback(VirkRegInfo regInfo)
|
||||
{
|
||||
Logger.LogDebug("CrmCompanyView => SelectCompanyCallback => {}", JsonSerializer.Serialize(regInfo));
|
||||
// this can be removed in favor of the new data returned from updating the VatNumber
|
||||
ValidVat = regInfo.States[0].State.ToLower() == "normal";
|
||||
Company.HasFolded = ValidVat ? 1 : 0;
|
||||
_infoDrawer.Content.HasFolded = ValidVat ? 1 : 0;
|
||||
EnableActivity = ValidVat ? 1 : 0;
|
||||
VatState = regInfo.States[0].State.ToLower() == "normal" ? "the-good" : "the-dead";
|
||||
// set new properties
|
||||
/*
|
||||
* set new properties if flagged
|
||||
*/
|
||||
if (regInfo.SyncAll)
|
||||
{
|
||||
Company.Name = regInfo.Name;
|
||||
Company.Address1 = regInfo.Address;
|
||||
Company.Address2 = regInfo.CoName;
|
||||
Company.ZipCode = regInfo.ZipCode;
|
||||
Company.City = regInfo.City;
|
||||
_infoDrawer.Content.Name = regInfo.Name;
|
||||
_infoDrawer.Content.Address1 = regInfo.Address;
|
||||
_infoDrawer.Content.Address2 = regInfo.CoName;
|
||||
_infoDrawer.Content.ZipCode = regInfo.ZipCode;
|
||||
_infoDrawer.Content.City = regInfo.City;
|
||||
}
|
||||
|
||||
Company.VatNumber = regInfo.VatNumber;
|
||||
_infoDrawer.Content.VatNumber = regInfo.VatNumber;
|
||||
}
|
||||
|
||||
|
||||
private void OpenContactPopup(ContactDto contact)
|
||||
{
|
||||
// write contact to debug log
|
||||
Logger.LogDebug("CompanyView => OpenContactPopup => contact => {}", JsonSerializer.Serialize(contact));
|
||||
|
||||
// object to pass on to the popup
|
||||
/*
|
||||
* pass contact to popup
|
||||
*/
|
||||
SelectedContact = contact;
|
||||
|
||||
Logger.LogDebug("CompanyView => OpenContactPopup => SelectedContact => {}", JsonSerializer.Serialize(SelectedContact));
|
||||
|
||||
// show the popup
|
||||
/*
|
||||
* show the popup
|
||||
*/
|
||||
ContactViewPopup.Show();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create request to update contact information
|
||||
/// </summary>
|
||||
/// <param name="contact"></param>
|
||||
private async Task WriteContactCallback(ContactDto contact)
|
||||
{
|
||||
if (Working)
|
||||
return;
|
||||
Working = true;
|
||||
// write contact to debug log
|
||||
var jsonContact = JsonSerializer.Serialize(contact);
|
||||
Logger.LogDebug("CompanyView => SaveContactCallback <= {}", jsonContact);
|
||||
/*
|
||||
* if ContactId is empty it is a new contact
|
||||
*/
|
||||
if (string.IsNullOrWhiteSpace(contact.ContactId))
|
||||
{
|
||||
// new contact created
|
||||
Logger.LogDebug("create => {}", jsonContact);
|
||||
// send post request to backend
|
||||
await CrmContactRepo.CreateContact(contact);
|
||||
/*
|
||||
* contact created - send post request to backend
|
||||
*/
|
||||
await ContactRepo.PostContact(contact);
|
||||
}
|
||||
else
|
||||
{
|
||||
// contact modified
|
||||
Logger.LogDebug("update => {}", jsonContact);
|
||||
// send put request to backend
|
||||
await CrmContactRepo.UpdateContact(contact);
|
||||
/*
|
||||
* contact modified - send put request
|
||||
*/
|
||||
await ContactRepo.PutContact(contact);
|
||||
}
|
||||
|
||||
// reset selected contact
|
||||
/*
|
||||
* reset default contact
|
||||
*/
|
||||
SelectedContact = new ContactDto();
|
||||
// reload contacts from backend
|
||||
await FetchContacts(CompanyId);
|
||||
/*
|
||||
* reload contacts from backend
|
||||
*/
|
||||
await GetContacts(CompanyId);
|
||||
Working = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete contact callback
|
||||
/// Delete contact information
|
||||
/// </summary>
|
||||
/// <param name="contactId"></param>
|
||||
private async Task DeleteContactCallback(string contactId)
|
||||
{
|
||||
if (Working)
|
||||
return;
|
||||
Working = true;
|
||||
Logger.LogDebug("delete {}", contactId);
|
||||
// send delete request to backend
|
||||
await CrmContactRepo.DeleteContact(CompanyId, contactId);
|
||||
// reset selected contact
|
||||
/*
|
||||
* send delete request to backend
|
||||
*/
|
||||
await ContactRepo.DeleteContact(CompanyId, contactId);
|
||||
/*
|
||||
* reset default contact
|
||||
*/
|
||||
SelectedContact = new ContactDto();
|
||||
// reload contacts from backend
|
||||
await FetchContacts(CompanyId);
|
||||
/*
|
||||
* reload contacts from backend
|
||||
*/
|
||||
await GetContacts(CompanyId);
|
||||
Working = false;
|
||||
}
|
||||
|
||||
|
@ -345,22 +382,21 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
|||
/// Update CRM data
|
||||
/// </summary>
|
||||
/// <returns>true/false</returns>
|
||||
private async Task UpdateCrmData()
|
||||
private async Task PostCrmData()
|
||||
{
|
||||
if (Working)
|
||||
return;
|
||||
Working = true;
|
||||
Toaster.ShowInfo("Vent venligst ...");
|
||||
Company.LastVisit = $"{LastVisit:yyyy-MM-dd}";
|
||||
Company.NextVisit = $"{NextVisit:yyyy-MM-dd}";
|
||||
Company.IsHidden = 0;
|
||||
var result = await CustomerRepo.UpdateCrmData(CompanyId, Company);
|
||||
if (!string.IsNullOrWhiteSpace(result.CompanyId))
|
||||
_infoDrawer.Content.LastVisit = $"{LastVisit:yyyy-MM-dd}";
|
||||
_infoDrawer.Content.NextVisit = $"{NextVisit:yyyy-MM-dd}";
|
||||
_infoDrawer.Content.IsHidden = 0;
|
||||
var company = await CustomerRepo.UpdateCrmData(CompanyId, _infoDrawer.Content);
|
||||
if (!string.IsNullOrWhiteSpace(company.CompanyId))
|
||||
{
|
||||
Company = result;
|
||||
await UpdateInfoDrawer(company);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
Working = false;
|
||||
Toaster.ClearAll();
|
||||
}
|
||||
|
@ -376,13 +412,12 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
|||
ErpEditDisabled = true;
|
||||
Working = true;
|
||||
Toaster.ShowInfo("Vent venligst ...");
|
||||
var result = await CustomerRepo.UpdateErpData(CompanyId, Company);
|
||||
if (!string.IsNullOrWhiteSpace(result.CompanyId))
|
||||
var company = await CustomerRepo.UpdateErpData(CompanyId, _infoDrawer.Content);
|
||||
if (!string.IsNullOrWhiteSpace(company.CompanyId))
|
||||
{
|
||||
Company = result;
|
||||
await UpdateInfoDrawer(company);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
Working = false;
|
||||
Toaster.ClearAll();
|
||||
}
|
||||
|
@ -393,8 +428,10 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
|||
/// <returns>true/false</returns>
|
||||
private async Task UpdateVatNumber()
|
||||
{
|
||||
// VAT format validation
|
||||
if (!VatUtils.ValidateFormat(Company.CountryCode, Company.VatNumber))
|
||||
/*
|
||||
* VAT format validation
|
||||
*/
|
||||
if (!VatUtils.ValidateFormat(_infoDrawer.Content.CountryCode, _infoDrawer.Content.VatNumber))
|
||||
{
|
||||
Toaster.ShowError($"Moms Nummer ugyldigt");
|
||||
return;
|
||||
|
@ -402,29 +439,30 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
|||
|
||||
if (Working)
|
||||
return;
|
||||
VatEditDisabled = true;
|
||||
Working = true;
|
||||
VatEditDisabled = true;
|
||||
Toaster.ShowInfo("Vent venligst ...");
|
||||
var result = await CustomerRepo.UpdateCompanyVat(CompanyId, Company.VatNumber);
|
||||
if (!string.IsNullOrWhiteSpace(result.CompanyId))
|
||||
var company = await CustomerRepo.UpdateCompanyVat(CompanyId, _infoDrawer.Content.VatNumber);
|
||||
if (!string.IsNullOrWhiteSpace(company.CompanyId))
|
||||
{
|
||||
Company = result;
|
||||
await UpdateInfoDrawer(company);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
Toaster.ClearAll();
|
||||
Working = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepare vat address from company model
|
||||
/// Prepare vat address from InfoDrawer.Company model
|
||||
/// </summary>
|
||||
/// <param name="company"></param>
|
||||
/// <returns></returns>
|
||||
private static VatAddress PrepareVatAddress(CompanyDto company)
|
||||
{
|
||||
var digits = "1234567890".ToCharArray();
|
||||
// process address1
|
||||
/*
|
||||
* process address1
|
||||
*/
|
||||
var pos1 = company.Address1.IndexOfAny(digits);
|
||||
if (pos1 > 0)
|
||||
{
|
||||
|
@ -432,11 +470,12 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
|||
{
|
||||
ZipCode = company.ZipCode.Trim(),
|
||||
StreetName = company.Address1[..pos1].Trim(),
|
||||
HouseNumber = Regex.Replace(company.Address1[pos1..], "[^0-9]", "").Trim()
|
||||
HouseNumber = company.Address1.Split('-')[0]
|
||||
};
|
||||
}
|
||||
|
||||
// process address2
|
||||
/*
|
||||
* process address2
|
||||
*/
|
||||
var pos2 = company.Address2.IndexOfAny(digits);
|
||||
if (pos2 > 0)
|
||||
{
|
||||
|
@ -444,17 +483,22 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
|||
{
|
||||
ZipCode = company.ZipCode.Trim(),
|
||||
StreetName = company.Address2[..pos2].Trim(),
|
||||
HouseNumber = Regex.Replace(company.Address2[pos2..], "[^0-9]", "").Trim()
|
||||
HouseNumber = company.Address2.Split('-')[0]
|
||||
};
|
||||
}
|
||||
|
||||
// return empty model
|
||||
/*
|
||||
* return empty model
|
||||
*/
|
||||
return new VatAddress();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change activity enabled state
|
||||
/// </summary>
|
||||
|
||||
private async Task UpdateInfoDrawer(CompanyDto company)
|
||||
{
|
||||
_infoDrawer.Content = company;
|
||||
await CabinetService.StoreInfoDrawerAsync(CompanyId, _infoDrawer);
|
||||
}
|
||||
|
||||
private void ForceActivity()
|
||||
{
|
||||
EnableActivity = EnableActivity == 0 ? 1 : 0;
|
||||
|
@ -468,11 +512,15 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
|||
private void HandleFieldChanged(object? sender, FieldChangedEventArgs? e)
|
||||
{
|
||||
|
||||
NextVisit = LastVisit.AddDays(Company.Interval * 7);
|
||||
// avoid nesting if by assuming ValidVat is false
|
||||
NextVisit = LastVisit.AddDays(_infoDrawer.Content.Interval * 7);
|
||||
/*
|
||||
* avoid nesting if by assuming ValidVat is false
|
||||
*/
|
||||
ValidVat = false;
|
||||
// set ValidVat true if validation succeed
|
||||
if (VatUtils.ValidateFormat(Company.CountryCode, Company.VatNumber))
|
||||
/*
|
||||
* set ValidVat true if validation succeed
|
||||
*/
|
||||
if (VatUtils.ValidateFormat(_infoDrawer.Content.CountryCode, _infoDrawer.Content.VatNumber))
|
||||
{
|
||||
ValidVat = true;
|
||||
EnableActivity = 1;
|
||||
|
@ -491,7 +539,7 @@ public partial class AdvisorCustomerViewEditPage : IDisposable
|
|||
ErpContext.OnFieldChanged -= HandleFieldChanged;
|
||||
ErpContext.OnValidationStateChanged -= ValidationChanged!;
|
||||
|
||||
ErpContext = new EditContext(Company);
|
||||
ErpContext = new EditContext(_infoDrawer.Content);
|
||||
|
||||
ErpContext.OnFieldChanged += HandleFieldChanged;
|
||||
ErpContext.OnValidationStateChanged += ValidationChanged!;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<h2>Support Dokumentation</h2>
|
||||
</div>
|
||||
<div class="col-sm-2 text-end">
|
||||
<a class="btn btn-primary" href="/supervisor" ><i class="bi-chevron-left"></i> Supervisor</a>
|
||||
<a class="btn btn-primary" href="/supervisor"><i class="bi-chevron-left"></i> Supervisor</a>
|
||||
</div>
|
||||
<div class="col-sm-2 text-end">
|
||||
<a class="btn btn-primary" href="/supervisor/advisors/@AdvisorId/documents"><i class="bi-chevron-left"></i> Tilbage</a>
|
||||
|
@ -38,7 +38,7 @@
|
|||
@* placeholder *@
|
||||
</div>
|
||||
<div class="col-sm-2 text-end">
|
||||
<div class="busy-signal @(Working ? "inno-visible" : "inno-hidden")" >
|
||||
<div class="busy-signal @(Working ? "inno-visible" : "inno-hidden")">
|
||||
<div class="spinner-grow text-info" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
|
@ -81,9 +81,11 @@
|
|||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="row">
|
||||
<Authorized Context="Management">
|
||||
<div class="col text-start">
|
||||
<button type="button" class="btn btn-warning" @onclick="@RemoveDocument"><i class="bi-trash"></i> Slet</button>
|
||||
</div>
|
||||
</Authorized>
|
||||
<div class="col text-end">
|
||||
<button type="submit" class="btn btn-primary"><i class="bi-cloud-upload"></i> Gem</button>
|
||||
</div>
|
||||
|
|
|
@ -28,7 +28,6 @@ using Wonky.Client.HttpRepository;
|
|||
using Wonky.Client.Local.Services;
|
||||
using Wonky.Client.Shared;
|
||||
using Wonky.Entity.Configuration;
|
||||
using Wonky.Entity.DTO;
|
||||
|
||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
builder.RootComponents.Add<App>("#app");
|
||||
|
@ -88,8 +87,6 @@ builder.Services.AddScoped<ISystemSendMailService, SystemSendMailService>();
|
|||
builder.Services.AddScoped<ISystemSendSmsService, SystemSendSmsService>();
|
||||
// interceptor
|
||||
builder.Services.AddScoped<HttpInterceptorService>();
|
||||
// storage
|
||||
builder.Services.AddBlazoredLocalStorage();
|
||||
// authorization
|
||||
builder.Services.AddAuthorizationCore();
|
||||
// authentication state provider
|
||||
|
@ -102,7 +99,10 @@ builder.Services.AddScoped<RefreshTokenService>();
|
|||
builder.Services.AddScoped<VatInfoLookupService>();
|
||||
// activity draft service
|
||||
builder.Services.AddScoped<OrderDraftService>();
|
||||
|
||||
// cabinet service
|
||||
builder.Services.AddScoped<IDrawerCabinetService, DrawerCabinetService>();
|
||||
// storage
|
||||
builder.Services.AddBlazoredLocalStorage();
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ public class AuthStateProvider : AuthenticationStateProvider
|
|||
private readonly IUserInfoService _infoService;
|
||||
|
||||
private readonly ILogger<AuthStateProvider> _logger;
|
||||
private bool DebugMe { get; set; } = false;
|
||||
|
||||
public AuthStateProvider(HttpClient client, IUserInfoService infoService, ILogger<AuthStateProvider> logger)
|
||||
{
|
||||
|
@ -44,25 +45,29 @@ public class AuthStateProvider : AuthenticationStateProvider
|
|||
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
|
||||
{
|
||||
var token = await _infoService.GetAccessToken();
|
||||
_logger.LogDebug("accessToken {}", token);
|
||||
|
||||
if (DebugMe) _logger.LogDebug("accessToken {}", token);
|
||||
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
return _anonymous;
|
||||
}
|
||||
|
||||
var userInfo = await _infoService.GetUserInfo();
|
||||
_logger.LogDebug("userInfo {}", JsonSerializer.Serialize(userInfo));
|
||||
|
||||
if (DebugMe) _logger.LogDebug("userInfo {}", JsonSerializer.Serialize(userInfo));
|
||||
|
||||
if (userInfo == null || string.IsNullOrWhiteSpace(userInfo.FirstName))
|
||||
{
|
||||
NotifyUserLogout();
|
||||
return _anonymous;
|
||||
}
|
||||
_logger.LogDebug("userInfo.FirstName {}", userInfo.FirstName);
|
||||
if (DebugMe) _logger.LogDebug("userInfo.FirstName {}", userInfo.FirstName);
|
||||
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
|
||||
|
||||
var exp = await _infoService.GetExpiration();
|
||||
_logger.LogDebug("expiration {}", exp);
|
||||
if (DebugMe) _logger.LogDebug("expiration {}", exp);
|
||||
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
|
@ -95,7 +100,9 @@ public class AuthStateProvider : AuthenticationStateProvider
|
|||
}
|
||||
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
|
||||
|
||||
var userInfo = await _infoService.GetUserInfo();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(userInfo.UserId))
|
||||
{
|
||||
NotifyUserLogout();
|
||||
|
|
|
@ -18,7 +18,7 @@ using Microsoft.AspNetCore.Components;
|
|||
|
||||
namespace Wonky.Client.Shared;
|
||||
|
||||
public partial class ConfirmWorkDateModal
|
||||
public partial class ConfirmWorkDateOverlay
|
||||
{
|
||||
private string _modalDisplay = "";
|
||||
private bool _showBackdrop;
|
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"appInfo": {
|
||||
"name": "Wonky Online",
|
||||
"version": "158.0",
|
||||
"version": "161.0",
|
||||
"rc": true,
|
||||
"sandBox": false,
|
||||
"image": "grumpy-coder.png"
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Debug",
|
||||
"Default": "Information",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
},
|
||||
"Debug": {
|
||||
|
@ -19,7 +19,7 @@
|
|||
}
|
||||
},
|
||||
"apiConfig": {
|
||||
"baseUrl": "https://dev.innotec.dk",
|
||||
"baseUrl": "https://zeta.innotec.dk",
|
||||
"catalog": "api/v2/catalog/country",
|
||||
"crmCustomers": "api/v2/crm/companies",
|
||||
"crmInventoryExt": "history/inventory",
|
||||
|
|
Loading…
Reference in a new issue