report calculation and code cleanup

This commit is contained in:
Frede Hundewadt 2023-11-02 18:25:58 +01:00
parent 900894f0f4
commit 258909077a
42 changed files with 260 additions and 187 deletions

View file

@ -14,62 +14,53 @@
*@ *@
@using Wonky.Entity.Views @using Wonky.Entity.Views
@* Report activities *@ @* Report activities *@
<table class="table table-sm table-striped d-print-table"> <table class="table table-sm table-striped">
<thead> <thead class="table-dark">
<tr> <tr>
<th scope="col" class="inno-thead">Kunde</th> <th scope="col" class="ps-2">Kunde</th>
<th scope="col" class="inno-thead">Bynavn</th> <th scope="col">Bynavn</th>
<th scope="col" class="inno-thead">Demo</th> <th scope="col">Demo</th>
<th scope="col" class="inno-thead">Salg</th> <th scope="col">Salg</th>
<th scope="col" class="inno-thead">Note</th> <th scope="col">Note</th>
<th scope="col" class="inno-thead text-end">SAS</th> <th scope="col">SAS</th>
<th scope="col" class="inno-thead text-end">Beløb</th> <th scope="col">Beløb</th>
<th scope="col" class="inno-thead text-center"> <th scope="col"><i style="font-size:1.3em;" class="bi-phone"></i></th>
<i style="font-size:1.3em;" class="bi-phone"></i> <th scope="col"><i class="bi-lightning-charge"></i></th>
</th> <th scope="col"><i class="bi-calculator"></i></th>
<th scope="col" class="inno-thead text-center"> <th scope="col"><i class="bi-truck"></i></th>
<i class="bi-lightning-charge"></i>
</th>
<th scope="col" class="inno-thead text-center">
<i class="bi-calculator"></i>
</th>
<th scope="col" class="inno-thead text-center">
<i class="bi-truck"></i>
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach (var activity in Activities) @foreach (var activity in Activities)
{ {
<tr> <tr>
<td class="text-sm-start">@activity.Company.Name</td> <td class="text-sm-start ps-2">@activity.Company.Name</td>
<td class="text-sm-start">@activity.Company.City</td> <td class="text-sm-start">@activity.Company.City</td>
<td class="text-sm-start">@activity.Demo</td> <td class="text-sm-start">@activity.Demo</td>
<td class="text-sm-start">@activity.Sales</td> <td class="text-sm-start">@activity.Sales</td>
<td class="text-sm-start">@activity.OfficeNote</td> <td class="text-sm-start">@activity.OfficeNote</td>
<td class="text-end">@($"{activity.SasAmount:N2}")</td> <td class="text-sm-end">@($"{activity.SasAmount:N2}")</td>
<td class="text-center">@(activity.StatusTypeEnum.Contains("Quote") ? "{0:N2}" : $"{activity.OrderAmount - activity.SasAmount:N2}")</td> <td class="text-sm-center">@(activity.StatusTypeEnum.Contains("Quote") ? "{0:N2}" : $"{activity.OrderAmount - activity.SasAmount:N2}")</td>
<td class="align-middle text-center"> <td class="align-middle text-sm-center">
@if (activity.OurRef.Contains("T:") || activity.OurRef.Contains("TLF:")) @if (activity.OurRef.Contains("T:") || activity.OurRef.Contains("TLF:"))
{<i style="font-size:1.3em;" class="bi-phone"></i>} {<i class="bi-phone"></i>}
@if (activity.OurRef.Contains("WEB:")) @if (activity.OurRef.Contains("WEB:"))
{<i style="font-size:1.3em;" class="bi-app"></i>} {<i class="bi-app"></i>}
</td> </td>
<td class="text-center"> <td class="text-sm-center">
@if (activity.Express) @if (activity.Express)
{ {
<i style="font-size:1.5em;" class="bi-lightning-charge"></i> <i class="bi-lightning-charge"></i>
} }
</td> </td>
<td class="text-center"> <td class="text-sm-center">
@if (activity.StatusTypeEnum == "Quote") @if (activity.StatusTypeEnum == "Quote")
{ {
<i style="font-size:1.5em;" class="bi-calculator"></i> <i class="bi-calculator"></i>
} }
</td> </td>
<td class="text-center"> <td class="text-sm-center">
<ProcessStateComponent StateClass="@activity.ProcessStatusEnum"/> <ProcessStateComponent StateClass="@activity.ProcessStatusEnum"/>
</td> </td>
</tr> </tr>
@ -77,3 +68,4 @@
</tbody> </tbody>
</table> </table>

View file

@ -21,4 +21,7 @@ namespace Wonky.Client.Components;
public partial class ActivityListComponent public partial class ActivityListComponent
{ {
[Parameter] public List<ReportItemView> Activities { get; set; } = new(); [Parameter] public List<ReportItemView> Activities { get; set; } = new();
[Parameter] public string ViewUrl { get; set; } = "";
} }

View file

@ -13,4 +13,4 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
*@ *@
<i style="font-size:1.3em;" class="bi-@Icon @StateClass"></i> <i class="bi-@Icon @StateClass"></i>

View file

@ -23,7 +23,7 @@ public partial class ProcessStateComponent
protected override void OnParametersSet() protected override void OnParametersSet()
{ {
Icon = StateClass switch Icon = StateClass.ToLower() switch
{ {
"the-fast" => "lightning-charge", "the-fast" => "lightning-charge",
"the-good" => "file-earmark", "the-good" => "file-earmark",

View file

@ -18,7 +18,7 @@
@if (ActivityList.Any()) @if (ActivityList.Any())
{ {
<table class="table table-sm table-bordered d-print-table table-striped"> <table class="table table-sm table-bordered table-striped">
<thead class="table-dark"> <thead class="table-dark">
<tr class="border-bottom"> <tr class="border-bottom">
<th scope="col">Kunde</th> <th scope="col">Kunde</th>

View file

@ -19,7 +19,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Components; namespace Wonky.Client.Components;
public partial class ActivityListOfficeReportComponent public partial class ReportActivityListOfficeComponent
{ {
[Parameter] public List<ReportItemView> ActivityList { get; set; } = new(); [Parameter] public List<ReportItemView> ActivityList { get; set; } = new();
[Inject] public NavigationManager Navigator { get; set; } [Inject] public NavigationManager Navigator { get; set; }

View file

@ -19,7 +19,7 @@
<span>ReportActivityListShowDocumentCallbackComponent.razor</span> <span>ReportActivityListShowDocumentCallbackComponent.razor</span>
@if (Activities.Any()) @if (Activities.Any())
{ {
<table class="table table-sm table-bordered d-print-table table-striped"> <table class="table table-sm table-bordered table-striped">
<thead class="table-dark"> <thead class="table-dark">
<tr class="border-bottom"> <tr class="border-bottom">
<th scope="col">Kunde</th> <th scope="col">Kunde</th>

View file

@ -15,7 +15,7 @@
<table class="table table-sm table-bordered table-striped"> <table class="table table-sm table-bordered table-striped">
<thead> <thead>
<tr class="bg-dark text-white opacity-75 border-bottom"> <tr class="table-dark">
<th colspan="3"> <th colspan="3">
Rapport Rapport
</th> </th>

View file

@ -17,7 +17,7 @@
@using Wonky.Entity.Views @using Wonky.Entity.Views
<div class="report-visit d-block"> <div class="report-visit d-block">
<table class="table table-sm table-striped d-print-table"> <table class="table table-sm table-striped">
<thead> <thead>
<tr> <tr>
<th class="p-0" colspan="4"> <th class="p-0" colspan="4">
@ -137,7 +137,7 @@
} }
</tbody> </tbody>
</table> </table>
@if (!string.IsNullOrWhiteSpace(@ReportItem.OfficeNote)) @if (!string.IsNullOrWhiteSpace(ReportItem.OfficeNote))
{ {
<div class="alert d-print-block border border-1 border-dark"> <div class="alert d-print-block border border-1 border-dark">
<p class="text-center h4"> <p class="text-center h4">

View file

@ -80,7 +80,7 @@ public class CountryProductCatalogRepository : ICountryProductCatalogRepository
["selectGroup"] = pager.SelectGroup == "0" ? "" : pager.SelectGroup ["selectGroup"] = pager.SelectGroup == "0" ? "" : pager.SelectGroup
}; };
var endpoint = WebUtils.QueryHelper($"{_api:CountryProductCatalog}/{countryCode}/page", queryDictionary); var endpoint = WebUtils.QueryHelper($"{_api.CountryProductCatalog}/{countryCode}/page", queryDictionary);
var response = await _client.GetAsync(endpoint); var response = await _client.GetAsync(endpoint);
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
@ -111,7 +111,7 @@ public class CountryProductCatalogRepository : ICountryProductCatalogRepository
/// <returns></returns> /// <returns></returns>
public async Task<ProductItemView> GetProductItemSku(string countryCode, string sku) public async Task<ProductItemView> GetProductItemSku(string countryCode, string sku)
{ {
var salesItem = await _client.GetFromJsonAsync<ProductItemView>($"{_api:CountryProductCatalog}/{countryCode}/sku/{sku}"); var salesItem = await _client.GetFromJsonAsync<ProductItemView>($"{_api.CountryProductCatalog}/{countryCode}/sku/{sku}");
return salesItem ?? new ProductItemView(); return salesItem ?? new ProductItemView();
} }
@ -124,7 +124,7 @@ public class CountryProductCatalogRepository : ICountryProductCatalogRepository
public async Task<ProductDetailView> GetProductDetailView(string salesItemId) public async Task<ProductDetailView> GetProductDetailView(string salesItemId)
{ {
var detailView = await _client var detailView = await _client
.GetFromJsonAsync<ProductDetailView>($"{_api:CountryProductCatalog}/{salesItemId}"); .GetFromJsonAsync<ProductDetailView>($"{_api.CountryProductCatalog}/{salesItemId}");
return detailView ?? new ProductDetailView(); return detailView ?? new ProductDetailView();
} }
@ -137,7 +137,7 @@ public class CountryProductCatalogRepository : ICountryProductCatalogRepository
public async Task<ProductDetailView> GetVariantDetailView(string variantId) public async Task<ProductDetailView> GetVariantDetailView(string variantId)
{ {
var detailView = await _client var detailView = await _client
.GetFromJsonAsync<ProductDetailView>($"{_api:CountryProductCatalog}/variant/{variantId}"); .GetFromJsonAsync<ProductDetailView>($"{_api.CountryProductCatalog}/variant/{variantId}");
return detailView ?? new ProductDetailView(); return detailView ?? new ProductDetailView();
} }
} }

View file

@ -25,7 +25,7 @@ using Wonky.Entity.Requests;
using Wonky.Entity.Views; using Wonky.Entity.Views;
#pragma warning disable CS8618 #pragma warning disable CS8618
namespace Wonky.Client.Shared; namespace Wonky.Client.OverlayCustomer;
public partial class ContactViewEditModal public partial class ContactViewEditModal
{ {

View file

@ -39,7 +39,7 @@
</div> </div>
@if (ReportStatusView.ReportItems.Any()) @if (ReportStatusView.ReportItems.Any())
{ {
<AdvisorActivityListComponent ActivityList="ReportStatusView.ReportItems"/> <ActivityListComponent Activities="ReportStatusView.ReportItems"/>
} }
@if (Working) @if (Working)
{ {

View file

@ -100,6 +100,7 @@
<th class="text-end" scope="col">Pris</th> <th class="text-end" scope="col">Pris</th>
<th class="text-end" scope="col">R%</th> <th class="text-end" scope="col">R%</th>
<th class="text-end" scope="col">Beløb</th> <th class="text-end" scope="col">Beløb</th>
<th class="text-center">SAS</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -112,6 +113,7 @@
<td class="text-end">@($"{line.Price:N2}")</td> <td class="text-end">@($"{line.Price:N2}")</td>
<td class="text-end">@($"{line.Discount:N2}")</td> <td class="text-end">@($"{line.Discount:N2}")</td>
<td class="text-end">@($"{line.LineSum:N2}")</td> <td class="text-end">@($"{line.LineSum:N2}")</td>
<td class="text-center">@if(line.Sas){<i class="bi-check"></i>}</td>
</tr> </tr>
} }
<tr> <tr>

View file

@ -15,6 +15,7 @@
@using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components @using Wonky.Client.Components
@using Wonky.Client.OverlayCustomer
@attribute [Authorize(Roles = "Advisor")] @attribute [Authorize(Roles = "Advisor")]
@page "/advisor/customers/{CompanyId}" @page "/advisor/customers/{CompanyId}"
<PageTitle>Stamkort for @_company.Name</PageTitle> <PageTitle>Stamkort for @_company.Name</PageTitle>

View file

@ -26,6 +26,7 @@ using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository; using Wonky.Client.HttpRepository;
using Wonky.Client.Local.Services; using Wonky.Client.Local.Services;
using Wonky.Client.Models; using Wonky.Client.Models;
using Wonky.Client.OverlayCustomer;
using Wonky.Client.Shared; using Wonky.Client.Shared;
using Wonky.Entity.Configuration; using Wonky.Entity.Configuration;
using Wonky.Entity.DTO; using Wonky.Entity.DTO;

View file

@ -194,5 +194,5 @@
<WorkingThreeDots/> <WorkingThreeDots/>
} }
<ConfirmActionModal BodyMessage="@DeleteMessage" OnOkClicked="RemoveWorkplace" @ref="ConfirmActionWorkplace"/> <ConfirmationModal BodyMessage="@DeleteMessage" OnOkClicked="RemoveWorkplace" @ref="ConfirmActionWorkplace"/>
<ConfirmActionModal BodyMessage="@DeleteMessage" OnOkClicked="RemoveVariant" @ref="ConfirmActionVariant"/> <ConfirmationModal BodyMessage="@DeleteMessage" OnOkClicked="RemoveVariant" @ref="ConfirmActionVariant"/>

View file

@ -57,7 +57,7 @@ public partial class AdvisorCustomerWorkplaceViewEditPage : IDisposable
private bool Working { get; set; } = true; private bool Working { get; set; } = true;
private WorkplaceDocInfo WorkplaceDocInfo { get; set; } = new(); private WorkplaceDocInfo WorkplaceDocInfo { get; set; } = new();
private List<DocView> DocViews { get; set; } = new(); private List<DocView> DocViews { get; set; } = new();
private ConfirmActionModal ConfirmActionWorkplace { get; set; } private ConfirmationModal ConfirmActionWorkplace { get; set; }
private string DeleteMessage { get; set; } = ""; private string DeleteMessage { get; set; } = "";
private string LinkRecipients { get; set; } = ""; private string LinkRecipients { get; set; } = "";
private const string CopyText = "Kopier"; private const string CopyText = "Kopier";
@ -78,7 +78,7 @@ public partial class AdvisorCustomerWorkplaceViewEditPage : IDisposable
private string _linkButtonStyle = LinkStyle; private string _linkButtonStyle = LinkStyle;
private ApiConfig _config = new(); private ApiConfig _config = new();
private ConfirmActionModal ConfirmActionVariant { get; set; } private ConfirmationModal ConfirmActionVariant { get; set; }
private DocView SelectedItem { get; set; } = new(); private DocView SelectedItem { get; set; } = new();
private bool OnlyOne { get; set; } = true; private bool OnlyOne { get; set; } = true;

View file

@ -185,13 +185,13 @@
@if (_activities.Any()) @if (_activities.Any())
{ {
<div class="row"> <div class="row">
<AdvisorActivityListComponent ActivityList="_activities"/> <ActivityListComponent Activities="_activities"/>
</div> </div>
} }
} }
<div class="row"> <div class="row">
@* ledger summaries calculated *@ @* ledger summaries calculated *@
<ReportActivityLedgerComponent ReportData="Report.Figures"/> <ReportLedgerActivityComponent ReportDataView="Report.Figures"/>
</div> </div>
</EditForm> </EditForm>
@ -200,4 +200,5 @@
<WorkingThreeDots/> <WorkingThreeDots/>
} }
<ConfirmationModal BodyMessage="@_prompt" OnOkClicked="ConfirmReportCallback" OnCancelClicked="OnCancelCallback" @ref="_confirmModal"/> <ConfirmationModal BodyMessage="@_prompt" OnOkClicked="ConfirmReportCallback"
OnCancelClicked="OnCancelCallback" @ref="_confirmModal"/>

View file

@ -45,7 +45,7 @@ public partial class AdvisorReportCreatePage : IDisposable
private EditContext ReportContext { get; set; } private EditContext ReportContext { get; set; }
private ReportDto Report { get; set; } = new(); private ReportDto Report { get; set; } = new();
private List<ReportItemView> _activities = new(); private List<ReportItemView> _activities = new();
private ReportFiguresDto _initialValues = new(); private ReportFiguresView _initialValues = new();
private UserPreference _preference = new(); private UserPreference _preference = new();
private bool _formInvalid = true; private bool _formInvalid = true;
private bool _noFigures = true; private bool _noFigures = true;
@ -117,6 +117,7 @@ public partial class AdvisorReportCreatePage : IDisposable
Report.Figures.DistancePrivateMonth = 0; Report.Figures.DistancePrivateMonth = 0;
await GetKeyFigures(); await GetKeyFigures();
Logger.LogDebug("OnInitializedAsync => GetKeyFigures <= {}", JsonSerializer.Serialize(Report)); Logger.LogDebug("OnInitializedAsync => GetKeyFigures <= {}", JsonSerializer.Serialize(Report));
} }
@ -133,8 +134,8 @@ public partial class AdvisorReportCreatePage : IDisposable
return; return;
_working = true; _working = true;
Report.Figures = new ReportFiguresDto(); Report.Figures = new ReportFiguresView();
_initialValues = new ReportFiguresDto(); _initialValues = new ReportFiguresView();
_activities = new List<ReportItemView>(); _activities = new List<ReportItemView>();
var data = await AdvisorSalesReportRepo.InitializeReportData(_workDate); var data = await AdvisorSalesReportRepo.InitializeReportData(_workDate);
@ -312,8 +313,8 @@ public partial class AdvisorReportCreatePage : IDisposable
_thisWorkDate = DateTime.Parse(workDate); _thisWorkDate = DateTime.Parse(workDate);
_noFigures = true; _noFigures = true;
Report.Figures = new ReportFiguresDto(); Report.Figures = new ReportFiguresView();
_initialValues = new ReportFiguresDto(); _initialValues = new ReportFiguresView();
_activities = new List<ReportItemView>(); _activities = new List<ReportItemView>();
Report.Figures.KmEvening = 0; Report.Figures.KmEvening = 0;

View file

@ -45,14 +45,14 @@
</div> </div>
<div class="row"> <div class="row">
<div class="w-75"> <div class="w-75">
<ReportViewSummaryComponent ReportData="Report.ReportData"/> <ReportSummaryComponent ReportDataView="Report.ReportData"/>
</div> </div>
<div class="w-25"> <div class="w-25">
<ReportViewDistanceLedgerComponent ReportData="Report.ReportData"/> <ReportLedgerDistanceComponent ReportDataView="Report.ReportData"/>
</div> </div>
</div> </div>
<AdvisorActivityListComponent ActivityList="Report.ReportItems"/> <ActivityListComponent Activities="Report.ReportItems"/>
<ReportViewActivityLedgerComponent ReportData="Report.ReportData"/> <ReportLedgerActivityComponent ReportDataView="Report.ReportData"/>
} }
else else
{ {

View file

@ -14,6 +14,7 @@
// //
using System.Text.Json;
using Blazored.LocalStorage; using Blazored.LocalStorage;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Wonky.Client.Enums; using Wonky.Client.Enums;
@ -44,8 +45,8 @@ public partial class AdvisorReportViewPage : IDisposable
private bool Working { get; set; } private bool Working { get; set; }
private UserManagerEditView XUserInfo { get; set; } = new(); private UserManagerEditView XUserInfo { get; set; } = new();
private string ReturnUrl { get; set; } = ""; private string ReturnUrl { get; set; } = "";
protected override async Task OnInitializedAsync() protected override async Task OnParametersSetAsync()
{ {
Interceptor.RegisterEvent(); Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent(); Interceptor.RegisterBeforeSendEvent();
@ -53,6 +54,10 @@ public partial class AdvisorReportViewPage : IDisposable
XUserInfo = await UserInfoService.GetUserInfo(); XUserInfo = await UserInfoService.GetUserInfo();
PreferenceService.OnChange += ProfileServiceOnOnChange; PreferenceService.OnChange += ProfileServiceOnOnChange;
}
protected override async Task OnInitializedAsync()
{
await PreferenceService.SetWorkDate(DateTime.Parse(ReportDate)); await PreferenceService.SetWorkDate(DateTime.Parse(ReportDate));
if(!string.IsNullOrWhiteSpace(ReportDate)) if(!string.IsNullOrWhiteSpace(ReportDate))
@ -108,6 +113,8 @@ public partial class AdvisorReportViewPage : IDisposable
// fetch report // fetch report
Report = await AdvisorSalesReportRepo.GetReport(workDate); Report = await AdvisorSalesReportRepo.GetReport(workDate);
Logger.LogDebug("Report => {}", JsonSerializer.Serialize(Report));
// extract activities // extract activities
Activities = Report.ReportItems.Where(x => x.Lines.Any()).ToList(); Activities = Report.ReportItems.Where(x => x.Lines.Any()).ToList();

View file

@ -1,7 +1,11 @@
using System.Diagnostics;
using System.Text.Json;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Wonky.Client.HttpInterceptors; using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository; using Wonky.Client.HttpRepository;
using Wonky.Client.Local.Services;
using Wonky.Client.Models; using Wonky.Client.Models;
using Wonky.Client.OverlayB2B; using Wonky.Client.OverlayB2B;
using Wonky.Client.Shared; using Wonky.Client.Shared;
@ -17,10 +21,10 @@ public partial class BusinessOrderViewPage
// ############################################################## // ##############################################################
[Inject] public HttpInterceptorService Interceptor { get; set; } [Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IB2BRepository B2BRepo { get; set; } [Inject] public IB2BRepository B2BRepo { get; set; }
[Inject] public ILogger<BusinessOrderViewPage> Logger { get; set; }
[Inject] [Inject] public ICountryPriceCatalogRepository PriceCatalog { get; set; }
public ICountryPriceCatalogRepository PriceCatalog { get; set; } [Inject] public IOptions<ApiConfig> Config { get; set; }
[Inject] private IOptions<ApiConfig> Config { get; set; } [Inject] public IUserInfoService UserInfoService { get; set; }
// ############################################################## // ##############################################################
[CascadingParameter] private DraftStateProvider DraftProvider { get; set; } = new(); [CascadingParameter] private DraftStateProvider DraftProvider { get; set; } = new();
@ -28,6 +32,7 @@ public partial class BusinessOrderViewPage
[Parameter] public string CompanyId { get; set; } = ""; [Parameter] public string CompanyId { get; set; } = "";
// ############################################################## // ##############################################################
private UserManagerEditView UserInfo { get; set; } = new();
private B2BBusinessInfo _businessInfo = new(); private B2BBusinessInfo _businessInfo = new();
private B2BAdvisorInfo _advisorInfo = new(); private B2BAdvisorInfo _advisorInfo = new();
private List<ProductHistoryView> _productHistory = new(); private List<ProductHistoryView> _productHistory = new();
@ -36,5 +41,79 @@ public partial class BusinessOrderViewPage
private B2BProductPriceHistoryOverlay PriceHistoryOverlay { get; set; } private B2BProductPriceHistoryOverlay PriceHistoryOverlay { get; set; }
private ItemSelect _selectedItem = new(); private ItemSelect _selectedItem = new();
private ActivityDto Activity { get; set; } = new(); private ActivityDto Activity { get; set; } = new();
private DateTime SelectedDate { get; set; }
private bool Working { get; set; } = true;
protected override async Task OnInitializedAsync()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
// get info for logged in user
UserInfo = await UserInfoService.GetUserInfo();
Activity.ActivityVisitEnum = "web";
Activity.ActivityTypeEnum = "phone";
Activity.ActivityStatusEnum = "order";
Activity.Express = true;
Activity.OurRef = $"TLF:{UserInfo.FirstName}";
// setup edit context
// ActivityContext = new EditContext(Activity);
// ActivityContext.OnFieldChanged += HandleFieldChanged;
// ActivityContext.OnValidationStateChanged += ValidationChanged;
// // fetch customer
// Company = await CustomerRepo.GetByCustomerId(CountryCode, CompanyId);
// Logger.LogDebug("OfficeOrderCreate => Customer => {}", JsonSerializer.Serialize(Company));
// construct today's workdate
// Initialize date variable
SelectedDate = DateTime.Now;
var today = $"{SelectedDate:yyyy-MM-dd}";
Activity.ActivityDate = today;
// initiate a sync to ensure up-to-date product history
// if (Company.HistorySync != today)
// {
// Company.HistorySync = await HistoryRepo.RequestErpToCrmSync(CompanyId, Company.HistorySync, false);
// Logger.LogDebug("OfficeOrderCreate => RequestErpToCrmSync <= {}", Company.HistorySync);
// }
// fetch invoices
// CompanyInvoices = await HistoryRepo.GetInvoiceList(CountryCode, CompanyId);
// Logger.LogDebug("OfficeOrderCreate => Invoices => {}", JsonSerializer.Serialize(CompanyInvoices));
// fetch activities
// CompanyActivities = await CountryActivityRepo.GetActivityList(CompanyId);
// Logger.LogDebug("OfficeOrderCreate => Activities => {}", JsonSerializer.Serialize(CompanyActivities));
// fetch inventory
// CompanyInventory = await HistoryRepo.GetInventory(CountryCode, CompanyId);
// CompanyInventory = CompanyInventory.OrderBy(x => x.Description).ToList();
// Logger.LogDebug("OfficeOrderCreate => Inventory => {}", JsonSerializer.Serialize(CompanyInventory));
// get sales rep info
// SalesRep = await UserRepo.GetUserInfo(Company.SalesRepId);
// Logger.LogDebug("OfficeOrderCreate => SalesRep => {}", JsonSerializer.Serialize(SalesRep));
// assign salesRep and countryCode to activity
// Activity.SalesRep = _advisorInfo.SalesRep;
// Activity.CountryCode = SalesRep.CountryCode;
// Activity.SalesRepId = Company.SalesRepId;
// assign customer info into activity properties
// Activity.Account = Company.Account;
// Activity.VatNumber = Company.VatNumber;
// Activity.Email = Company.Email;
// Activity.Phone = Company.Phone;
// Activity.Mobile = Company.Mobile;
// Activity.Name = Company.Name;
// Activity.Address1 = Company.Address1;
// Activity.Address2 = Company.Address2;
// Activity.ZipCode = Company.ZipCode;
// Activity.City = Company.City;
// Activity.DlvName = Company.Name;
// Activity.DlvAddress1 = Company.Address1;
// Activity.DlvAddress2 = Company.Address2;
// Activity.DlvZipCode = Company.ZipCode;
// Activity.DlvCity = Company.City;
// Activity.BcId = Company.BcId;
// Activity.CompanyId = Company.CompanyId;
// assign activity properties
Working = false;
}
} }

View file

@ -39,12 +39,12 @@
</div> </div>
<div class="row"> <div class="row">
<div class="w-75"> <div class="w-75">
<ReportViewSummaryComponent ReportData="Report.ReportData"/> <ReportSummaryComponent ReportDataView="Report.ReportData"/>
</div> </div>
<div class="w-25"> <div class="w-25">
<ReportViewDistanceLedgerComponent ReportData="Report.ReportData"/> <ReportLedgerDistanceComponent ReportDataView="Report.ReportData"/>
</div> </div>
</div> </div>
<OfficeReportActivityListComponent ActivityList="Report.ReportItems"/> <ReportActivityListOfficeComponent ActivityList="Report.ReportItems"/>
<ReportViewActivityLedgerComponent ReportData="Report.ReportData"/> <ReportLedgerActivityComponent ReportDataView="Report.ReportData"/>
</div> </div>

View file

@ -27,7 +27,10 @@
Rapport Arkiv - @InfoAdvisor.FirstName @InfoAdvisor.LastName Rapport Arkiv - @InfoAdvisor.FirstName @InfoAdvisor.LastName
</div> </div>
</div> </div>
<OfficeReportListComponent OnShowReport="ShowThisReport" CountryCode="@CountryCode" UserId="@UserId" ReportList="@ActivityReports" /> <OfficeReportListComponent OnShowReport="ShowThisReport"
CountryCode="@CountryCode"
UserId="@UserId"
ReportList="@ActivityReports" />
</div> </div>

View file

@ -55,6 +55,7 @@ public partial class OfficeAdvisorReportListPage : IDisposable
} }
var reports = await ReportRepo.GetCountryReports(UserId); var reports = await ReportRepo.GetCountryReports(UserId);
if (reports.Any()) if (reports.Any())
ActivityReports = reports.OrderByDescending(x => x.ReportDate).ToList(); ActivityReports = reports.OrderByDescending(x => x.ReportDate).ToList();
} }

View file

@ -36,38 +36,40 @@
</div> </div>
</div> </div>
<div class="report-main d-print-print"> <div class="report-main d-print-block">
@if (!string.IsNullOrWhiteSpace(Report.ReportData.DayTypeEnum)) @* <div class="w-100"> *@
{ @if (!string.IsNullOrWhiteSpace(Report.ReportData.DayTypeEnum))
<PageTitle>@Report.ReportData.Name</PageTitle> {
<div class="row"> <PageTitle>@Report.ReportData.Name</PageTitle>
<div class="alert border border-1 border-dark text-center align-content-center"> <div class="row">
<h3>@Report.ReportData.Name</h3> <div class="alert border border-1 border-dark text-center align-content-center">
<h3>@Report.ReportData.Name</h3>
</div>
</div> </div>
</div> <div class="row">
<div class="row"> <div class="w-75">
<div class="w-75"> <ReportSummaryComponent ReportDataView="Report.ReportData"/>
<ReportViewSummaryComponent ReportData="Report.ReportData"/> </div>
<div class="w-25">
<ReportLedgerDistanceComponent ReportDataView="Report.ReportData"/>
</div>
</div> </div>
<div class="w-25"> <ReportActivityListOfficeComponent ActivityList="Report.ReportItems"/>
<ReportViewDistanceLedgerComponent ReportData="Report.ReportData"/> <ReportLedgerActivityComponent ReportDataView="Report.ReportData"/>
}
else
{
<div class="row">
<div class="col">Ingen rapport data</div>
</div> </div>
</div> }
<OfficeReportActivityListComponent ActivityList="Report.ReportItems"/> @* </div> *@
<ReportViewActivityLedgerComponent ReportData="Report.ReportData"/>
}
else
{
<div class="row">
<div class="col">Ingen rapport data</div>
</div>
}
</div> </div>
@if (Activities.Any()) @if (Activities.Any())
{ {
foreach (var item in Activities.Where(item => item.StatusTypeEnum.ToLower() == "order" && item.ProcessStatusEnum.ToLower() == "none")) foreach (var item in Activities.Where(item => item.StatusTypeEnum.ToLower() == "order" && item.ProcessStatusEnum.ToLower() == "none"))
{ {
<ReportVisitComponent ReportItem="@item" /> <ReportVisitComponent ReportItem="@item"/>
} }
} }

View file

@ -88,10 +88,6 @@
<div class="col-sm-10 col-md-4"> <div class="col-sm-10 col-md-4">
<InputText id="phone" class="form-control" @bind-Value="Activity.Phone"/> <InputText id="phone" class="form-control" @bind-Value="Activity.Phone"/>
<ValidationMessage For="@(() => Activity.Phone)"></ValidationMessage> <ValidationMessage For="@(() => Activity.Phone)"></ValidationMessage>
<div class="form-check">
<InputCheckbox id="express" class="form-check-input" @bind-Value="@Activity.Express"/>
<label class="form-check-label" for="express">Express</label>
</div>
</div> </div>
<div class="col-sm-4 d-grid mx-auto"> <div class="col-sm-4 d-grid mx-auto">

View file

@ -150,9 +150,10 @@ public partial class OfficeCustomerOrderCreatePage : IDisposable
Activity.BcId = Company.BcId; Activity.BcId = Company.BcId;
Activity.CompanyId = Company.CompanyId; Activity.CompanyId = Company.CompanyId;
// assign activity properties // assign activity properties
Activity.ActivityVisitEnum = "none"; Activity.ActivityVisitEnum = "office";
Activity.ActivityTypeEnum = "phone"; Activity.ActivityTypeEnum = "phone";
Activity.ActivityStatusEnum = "order"; Activity.ActivityStatusEnum = "order";
Activity.Express = true;
Activity.OurRef = $"TLF:{UserInfo.FirstName}"; Activity.OurRef = $"TLF:{UserInfo.FirstName}";
Working = false; Working = false;
@ -244,20 +245,22 @@ public partial class OfficeCustomerOrderCreatePage : IDisposable
return; return;
// validate customer address1 // validate customer address1
// - this is a required input // - this is a required input
if (string.IsNullOrWhiteSpace(Activity.Address1)) // --- exclude for office orders
{ // if (string.IsNullOrWhiteSpace(Activity.Address1))
Toaster.ShowError("Kunde adresse er ufuldstændig."); // {
return; // Toaster.ShowError("Kunde adresse er ufuldstændig.");
} // return;
// }
// validate org number // validate org number
// - this is a required input // - this is a required input
// - must validate according to country rules. // - must validate according to country rules.
if (!VatUtils.ValidateFormat(Company.CountryCode, Activity.VatNumber)) // --- exclude for office orders
{ // if (!VatUtils.ValidateFormat(Company.CountryCode, Activity.VatNumber))
Toaster.ShowError("Firma registreringsnummer er ikke korrekt."); // {
return; // Toaster.ShowError("Firma registreringsnummer er ikke korrekt.");
} // return;
// }
// validate input according to status // validate input according to status
switch (Activity.ActivityStatusEnum) switch (Activity.ActivityStatusEnum)
@ -271,9 +274,10 @@ public partial class OfficeCustomerOrderCreatePage : IDisposable
Toaster.ShowError("Ved bestilling til ny kunde skal telefon nummer angives."); Toaster.ShowError("Ved bestilling til ny kunde skal telefon nummer angives.");
return; return;
// verify email address is a valid address // verify email address is a valid address
case "quote" when !Utils.IsValidEmail(Activity.Email): // --- exclude for office orders
Toaster.ShowError("Ved tilbud skal en gyldig email adresse angives."); // case "quote" when !Utils.IsValidEmail(Activity.Email):
return; // Toaster.ShowError("Ved tilbud skal en gyldig email adresse angives.");
// return;
} }
// raise working flag // raise working flag

View file

@ -42,14 +42,14 @@
</div> </div>
<div class="row"> <div class="row">
<div class="w-75"> <div class="w-75">
<ReportViewSummaryComponent ReportData="Report.ReportData"/> <ReportSummaryComponent ReportDataView="Report.ReportData"/>
</div> </div>
<div class="w-25"> <div class="w-25">
<ReportViewDistanceLedgerComponent ReportData="Report.ReportData"/> <ReportLedgerDistanceComponent ReportDataView="Report.ReportData"/>
</div> </div>
</div> </div>
<ReportViewActivityListComponent ActivityList="Report.ReportItems" OnShowDocument="ShowDocument"/> <ReportActivityListShowDocumentCallbackComponent Activities="Report.ReportItems" OnShowDocument="ShowDocument"/>
<ReportViewActivityLedgerComponent ReportData="Report.ReportData"/> <ReportLedgerActivityComponent ReportDataView="Report.ReportData"/>
} }
else else
{ {

View file

@ -87,5 +87,5 @@ else
} }
<AuthorizeView Roles="Management"> <AuthorizeView Roles="Management">
<ConfirmActionModal BodyMessage="@_deleteMessage" OnOkClicked="RemoveDocuments" @ref="_confirmDeleteDocuments"/> <ConfirmationModal BodyMessage="@_deleteMessage" OnOkClicked="RemoveDocuments" @ref="_confirmDeleteDocuments"/>
</AuthorizeView> </AuthorizeView>

View file

@ -40,7 +40,7 @@ public partial class SupervisorDocumentListPage : IDisposable
private List<SupportDocumentEditView> Documents { get; set; } = new(); private List<SupportDocumentEditView> Documents { get; set; } = new();
private SupportAdvisorView Advisor { get; set; } = new(); private SupportAdvisorView Advisor { get; set; } = new();
private bool Working { get; set; } = true; private bool Working { get; set; } = true;
private ConfirmActionModal _confirmDeleteDocuments = new(); private ConfirmationModal _confirmDeleteDocuments = new();
private string _deleteMessage = ""; private string _deleteMessage = "";
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()

View file

@ -92,6 +92,6 @@
</div> </div>
<AuthorizeView Roles="Management"> <AuthorizeView Roles="Management">
<ConfirmActionModal BodyMessage="@_deleteMessage" OnOkClicked="RemoveDocument" @ref="_confirmDeleteDocument"/> <ConfirmationModal BodyMessage="@_deleteMessage" OnOkClicked="RemoveDocument" @ref="_confirmDeleteDocument"/>
</AuthorizeView> </AuthorizeView>

View file

@ -46,7 +46,7 @@ public partial class SupervisorDocumentViewEditPage : IDisposable
private EditContext FormContext { get; set; } private EditContext FormContext { get; set; }
private SupportDocumentEditView Document { get; set; } = new(); private SupportDocumentEditView Document { get; set; } = new();
private bool Working { get; set; } = true; private bool Working { get; set; } = true;
private ConfirmActionModal _confirmDeleteDocument = new(); private ConfirmationModal _confirmDeleteDocument = new();
private string _deleteMessage = ""; private string _deleteMessage = "";

View file

@ -3784,6 +3784,12 @@
<_ContentIncludedByDefault Remove="wwwroot\icons\zoom-out.svg" /> <_ContentIncludedByDefault Remove="wwwroot\icons\zoom-out.svg" />
<_ContentIncludedByDefault Remove="wwwroot\bootstrap\fonts\bootstrap-icons.woff" /> <_ContentIncludedByDefault Remove="wwwroot\bootstrap\fonts\bootstrap-icons.woff" />
<_ContentIncludedByDefault Remove="wwwroot\bootstrap\fonts\bootstrap-icons.woff2" /> <_ContentIncludedByDefault Remove="wwwroot\bootstrap\fonts\bootstrap-icons.woff2" />
<_ContentIncludedByDefault Remove="wwwroot\bootstrap\css\bootstrap-icons.css" />
<_ContentIncludedByDefault Remove="wwwroot\bootstrap\css\bootstrap-icons.json" />
<_ContentIncludedByDefault Remove="wwwroot\bootstrap\css\bootstrap-icons.min.css" />
<_ContentIncludedByDefault Remove="wwwroot\bootstrap\css\bootstrap-icons.scss" />
<_ContentIncludedByDefault Remove="wwwroot\bootstrap\css\fonts\bootstrap-icons.woff" />
<_ContentIncludedByDefault Remove="wwwroot\bootstrap\css\fonts\bootstrap-icons.woff2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -3800,5 +3806,9 @@
<None Remove="wwwroot\icons\**" /> <None Remove="wwwroot\icons\**" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\bootstrap\" />
</ItemGroup>
</Project> </Project>

View file

@ -1,7 +1,7 @@
{ {
"appInfo": { "appInfo": {
"name": "Wonky Online", "name": "Wonky Online",
"version": "259.0", "version": "273.0",
"rc": true, "rc": true,
"sandBox": true, "sandBox": true,
"image": "grumpy-coder.png", "image": "grumpy-coder.png",
@ -23,7 +23,7 @@
"assetUrl": "https://files.innotec.dk", "assetUrl": "https://files.innotec.dk",
"baseUrl": "https://dev.innotec.dk", "baseUrl": "https://dev.innotec.dk",
"countryPriceCatalog": "api/v2/catalog/country", "countryPriceCatalog": "api/v2/catalog/country",
"countryPublicCatalog": "api/v2/catalog/public", "countryProductCatalog": "api/v2/catalog/public",
"crmCustomers": "api/v2/crm/companies", "crmCustomers": "api/v2/crm/companies",
"crmReports": "api/v2/crm/advisors/reports", "crmReports": "api/v2/crm/advisors/reports",
"crmActivities": "api/v2/crm/advisors/activities", "crmActivities": "api/v2/crm/advisors/activities",

View file

@ -31,6 +31,11 @@
background-color: #a2a2ec; background-color: #a2a2ec;
} }
.table-* {
background-color: #030303;
color: white;
}
html, body { html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
} }

View file

@ -11,8 +11,10 @@
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png" > <link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png" >
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png" > <link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png" >
<link rel="mask-icon" href="safari-pinned-tab.svg" color="#5bbad5" > <link rel="mask-icon" href="safari-pinned-tab.svg" color="#5bbad5" >
<link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet" > <link href="/bootstrap/css/bootstrap.css" rel="stylesheet" >
<link href="/bootstrap/css/bootstrap-icons.min.css" rel="stylesheet" > <!-- <link href="/bootstrap/css/bootstrap-utilities.css" rel="stylesheet" >-->
<!-- <link href="/bootstrap/css/boostrap-grid.css" rel="stylesheet">-->
<link href="/bootstrap/bootstrap-icons-1.11.1/bootstrap-icons.min.css" rel="stylesheet" >
<link href="/flag-icons/flag-icons.css" rel="stylesheet" > <link href="/flag-icons/flag-icons.css" rel="stylesheet" >
<link href="/css/app.css" rel="stylesheet" > <link href="/css/app.css" rel="stylesheet" >
<link href="/css/print.css" rel="stylesheet" > <link href="/css/print.css" rel="stylesheet" >

View file

@ -36,7 +36,7 @@ public class ApiConfig
/// <summary> /// <summary>
/// Application uri for public product catalog /// Application uri for public product catalog
/// </summary> /// </summary>
public string CountryPublicCatalog { get; set; } = ""; public string CountryProductCatalog { get; set; } = "";
/// <summary> /// <summary>
/// Application uri for activity request /// Application uri for activity request

View file

@ -13,54 +13,26 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html] // along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
// //
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Wonky.Entity.Views;
namespace Wonky.Entity.DTO; namespace Wonky.Entity.DTO;
public class ReportDto public class ReportDto
{ {
/// <summary>
/// Report name
/// </summary>
/// <remarks>System generated</remarks>
public string Name { get; set; } = ""; public string Name { get; set; } = "";
/// <summary>
/// Sales day counter
/// </summary>
public int SalesDayNumber { get; set; } public int SalesDayNumber { get; set; }
/// <summary> [MaxLength(1000, ErrorMessage = "Du kan højst bruge 1000 tegn")]
/// Report description
/// </summary>
[MaxLength(1000, ErrorMessage = "Du kan højst bruge 1000 tegn")]
public string Description { get; set; } = ""; public string Description { get; set; } = "";
/// <summary> [MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
/// Supervisor
/// </summary>
[MaxLength(100, ErrorMessage = "Du kan højst bruge 100 tegn")]
public string SupervisedBy { get; set; } = ""; public string SupervisedBy { get; set; } = "";
/// <summary> [Required(ErrorMessage = "Dagtype skal angives")]
/// Day type enum as string
/// </summary>
[Required(ErrorMessage = "Dagtype skal angives")]
public string DayTypeEnum { get; set; } = ""; public string DayTypeEnum { get; set; } = "";
/// <summary>
/// Report timespan - start date time
/// </summary>
public string FromDateTime { get; set; } = ""; public string FromDateTime { get; set; } = "";
/// <summary>
/// Report timespan - end date time
/// </summary>
public string ToDateTime { get; set; } = ""; public string ToDateTime { get; set; } = "";
public ReportFiguresView Figures { get; set; } = new();
/// <summary> }
/// Report figures
/// </summary>
public ReportFiguresDto Figures { get; set; } = new();
}

View file

@ -21,19 +21,7 @@ namespace Wonky.Entity.DTO;
public class ReportInitDto public class ReportInitDto
{ {
/// <summary>
/// Flag to prevent activity to be added to report
/// </summary>
public bool ReportClosed { get; set; } public bool ReportClosed { get; set; }
public ReportFiguresView ReportData { get; set; } = new();
/// <summary>
/// Report figures
/// </summary>
public ReportFiguresDto ReportData { get; set; } = new();
/// <summary>
/// List of activities for report
/// </summary>
public List<ReportItemView> ReportItems { get; set; } = new(); public List<ReportItemView> ReportItems { get; set; } = new();
} }

View file

@ -14,7 +14,8 @@ public class ReportFiguresView
public decimal SasTurnoverMonth { get; set; } public decimal SasTurnoverMonth { get; set; }
public decimal TotalTurnover { get; set; } public decimal TotalTurnover { get; set; }
public decimal TotalTurnoverMonth { get; set; } public decimal TotalTurnoverMonth { get; set; }
public decimal WebTurnover { get; set; }
public decimal WebTurnoverMonth { get; set; }
public int Distance { get; set; } public int Distance { get; set; }
public int DistanceMonth { get; set; } public int DistanceMonth { get; set; }
public int DistancePrivate { get; set; } public int DistancePrivate { get; set; }
@ -45,5 +46,7 @@ public class ReportFiguresView
public int TotalSaleCount { get; set; } public int TotalSaleCount { get; set; }
public int TotalSaleCountMonth { get; set; } public int TotalSaleCountMonth { get; set; }
public int TotalVisitCount { get; set; } public int TotalVisitCount { get; set; }
public int TotalVisitCountMonth { get; set; } public int TotalVisitCountMonth { get; set; }
public int WebCount { get; set; }
public int WebCountMonth { get; set; }
} }

View file

@ -19,6 +19,6 @@ namespace Wonky.Entity.Views;
public class ReportView public class ReportView
{ {
public ReportData ReportData { get; set; } = new(); public ReportDataView ReportData { get; set; } = new();
public List<ReportItemView> ReportItems { get; set; } = new(); public List<ReportItemView> ReportItems { get; set; } = new();
} }