This commit is contained in:
Frede Hundewadt 2022-12-23 17:57:56 +01:00
parent 72e5fd5b42
commit 54815591af
27 changed files with 203 additions and 95 deletions

View file

@ -17,6 +17,6 @@
<select class="form-select bg-success text-bg-success" @bind-value="@SortCol" @bind-value:event="oninput" @onchange="OnSelectChanged">
<option value="-1" selected disabled>SORTERING</option>
<option value="name">Navn</option>
<option value="sku">Nummer</option>
<option value="name">Navn sort</option>
<option value="sku">Varenr sort</option>
</select>

View file

@ -17,6 +17,6 @@
<select class="form-select bg-success text-bg-success" @bind-value="@SortCol" @bind-value:event="oninput" @onchange="OnSelectionChanged">
<option value="-1" selected disabled>SORTERING</option>
<option value="name">Navn</option>
<option value="city">By</option>
<option value="name">Navne sort.</option>
<option value="city">By sort.</option>
</select>

View file

@ -17,30 +17,33 @@
@using System.Globalization
@if (ReportList.Any())
{
<div class="list-group list-group-flush">
<div class="list-group-item px-3 bg-black text-white opacity-75">
<div class="row">
<div class="fw-bold col">
Dato
</div>
<div class="fw-bold col">
Dag
</div>
<div class="fw-bold col">
Start
</div>
<div class="fw-bold col">
Slut
</div>
<div class="fw-bold col text-end">
Resultat
</div>
<div class="list-group list-group-flush">
<div class="list-group-item px-3 bg-black text-white opacity-75">
<div class="row">
<div class="fw-bold col">
Dato
</div>
<div class="fw-bold col">
Dag
</div>
<div class="fw-bold col">
Start
</div>
<div class="fw-bold col">
Slut
</div>
<div class="fw-bold col text-end">
Resultat
</div>
</div>
</div>
@if (ReportList.Any())
{
@foreach (var report in ReportList)
{
<ReportListItemComponent Report="report" ViewUrl="@($"/office/users/advisors/{CountryCode}/{UserId}/reports")" />
@*
<a class="list-group-item list-group-item-action" href="/office/users/advisors/@CountryCode/@UserId/reports/@report.ReportDate">
<div class="row">
<div class="col">
@ -82,10 +85,11 @@
</div>
</div>
</a>
*@
}
</div>
}
else
{
<div>Ingen data</div>
}
}
else
{
<div>Ingen data</div>
}
</div>

View file

@ -16,12 +16,12 @@
*@
<select class="form-select bg-info text-bg-info" @bind-value="@PageSize" @bind-value:event="oninput" @onchange="OnSelectChanged">
<option value="-1" selected disabled>RESULTATER</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="30">30</option>
<option value="50">50</option>
<option value="-1" selected disabled>ANTAL svar</option>
<option value="5">5 svar</option>
<option value="10">10 svar</option>
<option value="15">15 svar</option>
<option value="30">30 svar</option>
<option value="50">50 svar</option>
</select>

View file

@ -0,0 +1,68 @@
@*
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
*@
@using Wonky.Entity.Views
<a class="list-group-item list-group-item-action" href="@ViewUrl/@Report.ReportDate">
<div class="row">
<div class="col">
@Report.ReportDate
</div>
<div class="col">
@{
switch (Report.DayTypeEnum)
{
case "Sales":
<span>Salgsdag</span>
break;
case "SickLeave":
<span>Sygdom</span>
break;
case "Office":
<span>Kontordag</span>
break;
case "Meeting":
<span>Salgsmøde</span>
break;
case "Leave":
<span>Ferie</span>
break;
case "Supervisor":
<span>Medkørende Supervisor</span>
break;
}
}
</div>
<div class="col">
@(Report.DayTypeEnum == "Sales" ? Report.FromDateTime.Split(" ")[1] : Report.FromDateTime.Split(" ")[0])
</div>
<div class="col">
@(Report.DayTypeEnum == "Sales" ? Report.ToDateTime.Split(" ")[1] : Report.ToDateTime.Split(" ")[0])
</div>
<div class="col text-end">
@Report.Turnover
</div>
</div>
</a>
@code {
[Parameter]
public SalesReportListView Report { get; set; } = new();
[Parameter]
public string ViewUrl { get; set; } = "";
}

View file

@ -35,10 +35,13 @@
</div>
</div>
</div>
@if (_reports.Any())
@if (Reports.Any())
{
@foreach (var report in ReportList)
{
<ReportListItemComponent Report="report" ViewUrl="/sales-reports/view" />
@*
<a class="list-group-item list-group-item-action" href="/sales-reports/view/@report.ReportDate">
<div class="row">
<div class="col">
@ -80,6 +83,7 @@
</div>
</div>
</a>
*@
}
}
else

View file

@ -22,9 +22,9 @@ namespace Wonky.Client.Components;
public partial class ReportTableComponent
{
[Parameter] public List<SalesReportListView> ReportList { get; set; } = new();
private List<SalesReportListView> _reports { get; set; } = new();
private List<SalesReportListView> Reports { get; set; } = new();
protected override void OnParametersSet()
{
_reports = ReportList;
Reports = ReportList;
}
}

View file

@ -21,7 +21,7 @@ namespace Wonky.Client.Helpers;
public static class Utils
{
public static Dictionary<string, string> ParseQueryString(string query)
public static Dictionary<string, string> ParseQuery(string query)
{
if (string.IsNullOrWhiteSpace(query) || query.Contains("://"))
return new Dictionary<string, string>();

View file

@ -18,7 +18,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpInterfaces;
public interface IOfficeUserHttpRepository
public interface IUserHttpRepository
{
Task<List<UserListAdminView>> GetAdvisors();
Task<WebUserInfoView> GetAdvisorInfo(string userId);

View file

@ -25,7 +25,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.HttpRepository;
public class OfficeUserHttpRepository : IOfficeUserHttpRepository
public class UserHttpRepository : IUserHttpRepository
{
private readonly JsonSerializerOptions? _options = new JsonSerializerOptions
{
@ -33,11 +33,11 @@ public class OfficeUserHttpRepository : IOfficeUserHttpRepository
};
private readonly NavigationManager _navigation;
private ILogger<OfficeUserHttpRepository> _logger;
private ILogger<UserHttpRepository> _logger;
private readonly HttpClient _client;
private readonly ApiConfig _api;
public OfficeUserHttpRepository(HttpClient client, ILogger<OfficeUserHttpRepository> logger,
public UserHttpRepository(HttpClient client, ILogger<UserHttpRepository> logger,
NavigationManager navigation, IOptions<ApiConfig> configuration)
{
_client = client;

View file

@ -23,6 +23,7 @@
<h3>Rapport Arkiv</h3>
</div>
</div>
<ReportTableComponent ReportList="ReportList" />

View file

@ -24,7 +24,7 @@ namespace Wonky.Client.Pages;
public partial class CrmReportListPage : IDisposable
{
[Inject] public ICrmReportHttpRepository CrmReportRepo { get; set; }
[Inject] public ICrmReportHttpRepository ReportRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
private List<SalesReportListView> ReportList { get; set; } = new();
@ -34,8 +34,8 @@ public partial class CrmReportListPage : IDisposable
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
ReportList = await CrmReportRepo.GetReports();
await Task.Delay(1000);
ReportList = await ReportRepo.GetReports();
Working = false;
}

View file

@ -26,17 +26,17 @@
<WorkDateComponent OnChangedCallback="FetchReport"/>
</div>
<div class="col-sm-2 d-grid">
<button class="btn btn-warning" @onclick="() => Print(PTarget.Report)"><i class="bi-printer"></i> Rapport</button>
<button class="btn btn-warning" @onclick="() => Print(PTarget.Report)"><i class="bi-printer"></i> Forside</button>
</div>
<div class="col-sm-2 d-grid">
<button class="btn btn-success" @onclick="() => Print(PTarget.Order)"><i class="bi-printer"></i> Ordrer</button>
</div>
<div class="col-sm-2 d-grid">
<button class="btn btn-primary" type="button" onclick="window.print();"><i class="bi-printer"></i> Print</button>
<button class="btn btn-primary" type="button" onclick="window.print();"><i class="bi-printer"></i> Rapport</button>
</div>
</div>
<div class="report-main">
<div class="report-main d-print-grid">
@if (!string.IsNullOrWhiteSpace(Report.ReportData.DayTypeEnum))
{
<PageTitle>@Report.ReportData.Name</PageTitle>
@ -57,7 +57,7 @@
else
{
<div class="row">
<div class="col">Ingen data</div>
<div class="col">Ingen Rapport data</div>
</div>
}
</div>

View file

@ -29,17 +29,19 @@ public partial class CrmReportViewPage : IDisposable
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public ILogger<CrmReportViewPage> Logger { get; set; }
private ReportView Report { get; set; } = new();
private List<ReportItemView> Activities { get; set; } = new ();
private bool Working { get; set; } = true;
private bool Working { get; set; }
private UserInfoView UserInfo { get; set; } = new();
private string ReturnUrl { get; set; } = "";
protected override async Task OnParametersSetAsync()
protected override async Task OnInitializedAsync()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
UserInfo = await Storage.GetItemAsync<UserInfoView>("_xu");
await FetchReport(ReportDate);
if(!string.IsNullOrWhiteSpace(ReportDate))
await FetchReport(ReportDate);
}
private void Print(PTarget target)
@ -64,15 +66,32 @@ public partial class CrmReportViewPage : IDisposable
}
private async Task FetchReport(string workDate)
{
if(workDate != ReportDate)
Navigator.NavigateTo($"/sales-reports/view/{workDate}");
// remove busy signal if report is empty
if (string.IsNullOrWhiteSpace(Report.ReportData.ReportDate))
Working = false;
// return if we are already at it
if (Working)
{
return;
}
Working = true;
// reset variables
Report = new ReportView();
Activities = new List<ReportItemView>();
// set busy signal
Working = true;
// fetch report
Report = await ReportRepo.GetReport(workDate);
// extract activities
Activities = Report.ReportItems.Where(x => x.Lines.Any()).ToList();
await Storage.SetItemAsync($"{UserInfo.Id}-{Report.ReportData.ReportDate}", Report);
// store the report locally
if (!string.IsNullOrWhiteSpace(Report.ReportData.ReportDate))
{
await Storage.SetItemAsync($"{UserInfo.Id}-{Report.ReportData.ReportDate}", Report);
}
// remove busy signal
Working = false;
}

View file

@ -34,7 +34,7 @@ public partial class OfficeOrderNewPage : IDisposable
[Parameter] public string CompanyId { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IOfficeCustomerHttpRepository OfficeCustomerRepo { get; set; }
[Inject] public IOfficeUserHttpRepository OfficeUserRepo { get; set; }
[Inject] public IUserHttpRepository UserRepo { get; set; }
[Inject] public ICatalogHttpRepository CatalogRepo { get; set; }
[Inject] public ICrmActivityHttpRepository CrmActivityRepo { get; set; }
[Inject] public ILogger<OfficeOrderNewPage> Logger { get; set; }
@ -69,7 +69,7 @@ public partial class OfficeOrderNewPage : IDisposable
_editContext.OnFieldChanged += HandleFieldChanged;
_editContext.OnValidationStateChanged += ValidationChanged;
_userInfo = await OfficeUserRepo.GetAdvisorInfo(_company.SalesRepId);
_userInfo = await UserRepo.GetAdvisorInfo(_company.SalesRepId);
_activity.ActivityDate = $"{DateTime.Now:yyyy-MM-dd}" ;

View file

@ -38,7 +38,7 @@ public partial class OfficeOrderViewPage : IDisposable
[Inject] public ICrmActivityHttpRepository ActivityRepo { get; set; }
[Inject] public ISendMailService MailService { get; set; }
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public IOfficeUserHttpRepository UserRepo { get; set; }
[Inject] public IUserHttpRepository UserRepo { get; set; }
[Inject] public ILogger<OfficeOrderViewPage> Logger { get; set; }
[Inject] public IToastService Toast { get; set; }
private ReportItemView _reportItem { get; set; } = new();

View file

@ -24,7 +24,7 @@
<div class="card-header bg-dark text-white">
<div class="row">
<div class="col">
<h3>Rapport Arkiv</h3>
<h3>Rapport Arkiv - @UserInfo.FirstName @UserInfo.LastName</h3>
</div>
</div>
</div>

View file

@ -13,6 +13,7 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Components;
using Toolbelt.Blazor;
using Wonky.Client.HttpInterceptors;
@ -28,21 +29,25 @@ public partial class OfficeReportListPage : IDisposable
[Parameter] public string CountryCode { get; set; } = "";
[Inject] public IOfficeReportHttpRepository ReportRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IUserHttpRepository UserRepo { get; set; }
private List<SalesReportListView> ActivityReports { get; set; } = new();
private bool Working { get; set; } = true;
private WebUserInfoView UserInfo { get; set; } = new();
protected override async Task OnInitializedAsync()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
await Task.Delay(1000);
UserInfo = await UserRepo.GetAdvisorInfo(UserId);
await FetchReports();
Working = false;
}
private async Task FetchReports()
{
await Task.Delay(1000);
var reports = await ReportRepo.GetReports(UserId);
if (reports.Any())
ActivityReports = reports.OrderByDescending(x => x.ReportDate).ToList();

View file

@ -26,17 +26,17 @@
<WorkDateComponent OnChangedCallback="FetchUserReport"/>
</div>
<div class="col-sm-2 d-grid">
<button class="btn btn-warning" @onclick="() => Print(PTarget.Report)"><i class="bi-printer"></i> Rapport</button>
<button class="btn btn-warning" @onclick="() => Print(PTarget.Report)"><i class="bi-printer"></i> Forside</button>
</div>
<div class="col-sm-2 d-grid">
<button class="btn btn-success" @onclick="() => Print(PTarget.Order)"><i class="bi-printer"></i> Ordrer</button>
</div>
<div class="col-sm-2 d-grid">
<button class="btn btn-primary" type="button" onclick="window.print();"><i class="bi-printer"></i> Print</button>
<button class="btn btn-primary" type="button" onclick="window.print();"><i class="bi-printer"></i> Rapport</button>
</div>
</div>
<div class="report-main d-print-grid">
<div class="report-main d-print-print">
@if (!string.IsNullOrWhiteSpace(Report.ReportData.DayTypeEnum))
{
<PageTitle>@Report.ReportData.Name</PageTitle>

View file

@ -59,16 +59,16 @@ public partial class OfficeReportViewPage : IDisposable
/// </summary>
[Inject]
public NavigationManager Navigator { get; set; }
/// <summary>
/// Logger service
/// </summary>
[Inject] public ILogger<OfficeReportViewPage> Logger { get; set; }
/// <summary>
/// Storage service
/// </summary>
[Inject] public ILocalStorageService Storage { get; set; }
/// <summary>
/// Report to render
/// </summary>
private ReportView Report { get; set; } = new();
private PTarget ThisTarget { get; set; } = PTarget.All;
private List<ReportItemView> Activities { get; set; } = new();
private bool Working { get; set; } = true;
@ -106,23 +106,30 @@ public partial class OfficeReportViewPage : IDisposable
/// <param name="workDate"></param>
private async Task FetchUserReport(string workDate)
{
if (workDate != ReportDate)
{
Navigator.NavigateTo($"/office/users/advisors/{CountryCode}/{UserId}/reports/{workDate}");
// remove busy signal if report is empty
if (string.IsNullOrWhiteSpace(Report.ReportData.ReportDate))
Working = false;
// return if we are already at it
if (Working)
{
return;
}
Working = true;
// reset variables
Report = new ReportView();
Activities = new List<ReportItemView>();
// set busy signal
Working = true;
// fetch
Report = await ReportRepo.GetReport(UserId, workDate);
// assign activities
// extract activities
Activities = Report.ReportItems.Where(x => x.Lines.Any()).ToList();
// write to storage
await Storage.SetItemAsync($"{UserId}-{ReportDate}", Report);
// hide indicator
// store locally
if (!string.IsNullOrWhiteSpace(Report.ReportData.ReportDate))
{
await Storage.SetItemAsync($"{UserId}-{Report.ReportData.ReportDate}", Report);
}
// remove busy signal
Working = false;
}

View file

@ -26,7 +26,7 @@ public partial class OfficeUserListPage : IDisposable
{
[Parameter] public string CountryCode { get; set; } = "";
[Inject] public HttpInterceptorService _interceptor { get; set; }
[Inject] public IOfficeUserHttpRepository OfficeUserRepo { get; set; }
[Inject] public IUserHttpRepository UserRepo { get; set; }
private List<UserListAdminView> _salesReps { get; set; } = new();
private bool Working { get; set; } = true;
@ -35,7 +35,7 @@ public partial class OfficeUserListPage : IDisposable
{
_interceptor.RegisterEvent();
_interceptor.RegisterBeforeSendEvent();
var AdvisorList = await OfficeUserRepo.GetAdvisors();
var AdvisorList = await UserRepo.GetAdvisors();
_salesReps = AdvisorList
.Where(x => x.CountryCode.ToLower() == CountryCode && Convert.ToInt32(x.SalesRep) < 100)
.ToList();

View file

@ -31,7 +31,7 @@ public partial class OfficeUserViewPage : IDisposable
[Parameter] public string UserId { get; set; } = "";
[Parameter] public string CountryCode { get; set; } = "";
[Inject] public HttpInterceptorService _interceptor { get; set; }
[Inject] public IOfficeUserHttpRepository OfficeUserRepo { get; set; }
[Inject] public IUserHttpRepository UserRepo { get; set; }
[Inject] public ILogger<OfficeUserViewPage> _logger { get; set; }
[Inject] public NavigationManager _navigator { get; set; }
[Inject] public IToastService _toast { get; set; }
@ -56,7 +56,7 @@ public partial class OfficeUserViewPage : IDisposable
_interceptor.RegisterEvent();
_interceptor.RegisterBeforeSendEvent();
_userInfo = await OfficeUserRepo.GetAdvisorInfo(UserId);
_userInfo = await UserRepo.GetAdvisorInfo(UserId);
_updateInfo.Email = _userInfo.Email;
_updateInfo.CountryCode = _userInfo.CountryCode;
@ -75,7 +75,7 @@ public partial class OfficeUserViewPage : IDisposable
{
Working = true;
_toast.ShowInfo("Sender data til server ...");
await OfficeUserRepo.UpdateAdvisor(UserId, _updateInfo);
await UserRepo.UpdateAdvisor(UserId, _updateInfo);
Working = false;
}
@ -103,7 +103,7 @@ public partial class OfficeUserViewPage : IDisposable
if (Working)
return;
Working = true;
await OfficeUserRepo.ResetUserPassword(UserId, _passwords.NewPassword, _passwords.ConfirmPassword);
await UserRepo.ResetUserPassword(UserId, _passwords.NewPassword, _passwords.ConfirmPassword);
_toast.ShowInfo("Password er nulstillet.");
_passwords.NewPassword = "";
_passwords.ConfirmPassword = "";

View file

@ -21,7 +21,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class PrintOrdersPage
public partial class PrintOrderPage
{
[Parameter] public string CountryCode { get; set; } = "";
[Parameter] public string UserId { get; set; } = "";
@ -29,7 +29,7 @@ public partial class PrintOrdersPage
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
[Inject] private IJSRuntime JSRuntime { get; set; }
[Inject] public ILogger<PrintOrdersPage> Logger { get; set; }
[Inject] public ILogger<PrintOrderPage> Logger { get; set; }
private ReportView Report { get; set; } = new();
private List<ReportItemView> Items { get; set; } = new();
private IJSObjectReference JsModule { get; set; }
@ -46,7 +46,7 @@ public partial class PrintOrdersPage
protected override async Task OnInitializedAsync()
{
var uri = new Uri(Navigator.Uri);
var query = Utils.ParseQueryString(uri.Query[1..]);
var query = Utils.ParseQuery(uri.Query[1..]);
ReturnUrl = string.IsNullOrWhiteSpace(query["returnUrl"]) ? "/" : query["returnUrl"];
Report = await Storage.GetItemAsync<ReportView>($"{UserId}-{ReportDate}");

View file

@ -38,7 +38,7 @@ public partial class PrintReportPage
protected override async Task OnInitializedAsync()
{
var uri = new Uri(Navigator.Uri);
var query = Utils.ParseQueryString(uri.Query[1..]);
var query = Utils.ParseQuery(uri.Query[1..]);
ReturnUrl = string.IsNullOrWhiteSpace(query["returnUrl"]) ? "/" : query["returnUrl"];
Report = await Storage.GetItemAsync<ReportView>($"{UserId}-{ReportDate}");

View file

@ -62,7 +62,7 @@ builder.Services.AddScoped<ICrmReportHttpRepository, CrmReportHttpRepository>();
builder.Services.AddScoped<ICrmTaskItemHttpRepository, CrmTaskItemHttpRepository>();
builder.Services.AddScoped<ICrmWorkplaceHttpRepository, CrmWorkplaceHttpRepository>();
// administrative repositories
builder.Services.AddScoped<IOfficeUserHttpRepository, OfficeUserHttpRepository>();
builder.Services.AddScoped<IUserHttpRepository, UserHttpRepository>();
builder.Services.AddScoped<IOfficeReportHttpRepository, OfficeReportHttpRepository>();
builder.Services.AddScoped<IOfficeCustomerHttpRepository, OfficeCustomerHttpRepository>();
// warehouse repository

View file

@ -1,7 +1,7 @@
{
"appInfo": {
"name": "Wonky Client",
"version": "0.87.4",
"version": "0.87.7",
"rc": true,
"sandBox": false,
"image": "grumpy-coder.png"
@ -34,7 +34,7 @@
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
},