refactor linking to match usage (advisor, office, warehouse)

This commit is contained in:
Frede Hundewadt 2023-01-15 18:46:27 +01:00
parent b82bc43ded
commit 7342bfff77
108 changed files with 858 additions and 515 deletions

View file

@ -2,9 +2,12 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Affero/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bestilling/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bes_00F8g/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Danmark/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=fejl/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=kontrolleres/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Norge/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=opst_00E5et/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sverige/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tilbud/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Venligst/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Virk/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View file

@ -1,80 +0,0 @@
@using Wonky.Client.Helpers
@*
// 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]
//
*@
@if (ActivityList.Any())
{
<table class="table table-bordered d-print-table table-striped">
<thead>
<tr class="bg-dark text-white opacity-75 border-bottom">
<th scope="col">Kunde</th>
<th scope="col">Bynavn</th>
<th scope="col">Demo</th>
<th scope="col">Salg</th>
<th scope="col">Note</th>
<th class="text-end" scope="col">sas</th>
<th class="text-end" scope="col">Beløb</th>
<th class="text-center" scope="col"><i class="bi-phone"></i></th>
<th class="text-center" scope="col"><i class="bi-lightning"></i></th>
<th class="text-center" scope="col"><i class="bi-calculator"></i></th>
<th class="text-center" scope="col"><i class="bi-truck"></i></th>
</tr>
</thead>
<tbody>
@foreach (var activity in ActivityList)
{
<tr>
<td class="align-middle"><a class="btn btn-outline-info text-black d-block" href="/customers/@activity.Company.CompanyId/orders/@activity.ActivityId">@activity.Company.Name</a></td>
<td class="align-middle">@activity.Company.City</td>
<td class="align-middle">@activity.Demo</td>
<td class="align-middle">@activity.Sales</td>
<td class="align-middle">@activity.OfficeNote</td>
<td class="align-middle text-end">@($"{activity.SasAmount:N2}")</td>
<td class="align-middle text-end">@(activity.StatusTypeEnum == "Quote" ? $"{0:N2}" : $"{activity.OrderAmount:N2}")</td>
<td class="align-middle text-center">
@if (activity.OurRef.Contains("T:"))
{<i style="font-size:1.3em;" class="bi-phone"></i>}
</td>
<td class="align-middle text-center">
@if (activity.Express)
{<i style="font-size:1.3em;" class="bi-lightning"></i>}
</td>
<td class="align-middle text-end">
@if (activity.StatusTypeEnum == "Quote")
{<i style="font-size:1.3em;" class="bi-calculator"></i>}
</td>
<td class="align-middle state">
@if (activity.Lines.Any() && activity.StatusTypeEnum == "Order")
{
<ProcessStateComponent StateClass="@Utils.GetProcessStatus(activity.ProcessStatusEnum)"/>
}
</td>
</tr>
}
<tr>
<td colspan="5" class="bg-dark"></td>
<td class="align-middle text-center">Total</td>
<td class="align-middle text-end">@ActivityList.Where(x => x.StatusTypeEnum == "Order").Sum(x => x.OrderAmount)</td>
<td colspan="4" class="bg-dark"></td>
</tr>
</tbody>
</table>
}
else
{
<div>Ingen data</div>
}

View file

@ -1,3 +1,4 @@
@using Wonky.Client.Helpers
@*
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
@ -14,79 +15,66 @@
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
*@
@using Wonky.Entity.Views
@* Report activities *@
<table class="table table-striped">
<thead>
<tr class="bg-black opacity-75 text-white">
<th scope="col">Kunde</th>
<th scope="col">Bynavn</th>
<th scope="col">Demo</th>
<th scope="col">Salg</th>
<th scope="col">Note</th>
<th scope="col" class="text-end">sas</th>
<th scope="col" class="text-end">Beløb</th>
<th scope="col" class="text-center">
<i style="font-size:1.3em;" class="bi-phone"></i>
</th>
<th scope="col" class="text-center">
<i class="bi-lightning"></i>
</th>
<th scope="col" class="text-center">
<i class="bi-calculator"></i>
</th>
<th scope="col" class="text-center">
<i class="bi-truck"></i>
</th>
</tr>
</thead>
<tbody>
@foreach (var activity in Activities)
{
<tr>
<td class="text-sm-start">@activity.Company.Name</td>
<td class="text-sm-start">@activity.Company.City</td>
<td class="text-sm-start">@activity.Demo</td>
<td class="text-sm-start">@activity.Sales</td>
<td class="text-sm-start">@activity.OfficeNote</td>
<td class="text-end">@($"{activity.SasAmount:N2}")</td>
<td class="text-center">@(activity.StatusTypeEnum.Contains("Quote") ? $"{0:N2}" : $"{activity.OrderAmount:N2}")</td>
<td class="text-center">
@if (activity.OurRef.Contains("T:"))
{
<i style="font-size:1.5em;" class="bi-phone"></i>
}
</td>
<td class="text-center">
@if (activity.Express)
{
<i style="font-size:1.5em;" class="bi-lightning"></i>
}
</td>
<td class="text-center">
@if (activity.StatusTypeEnum == "Quote")
{
<i style="font-size:1.5em;" class="bi-calculator"></i>
}
</td>
<td class="text-center">
<ProcessStateComponent StateClass="@activity.ProcessStatusEnum"/>
</td>
@if (ActivityList.Any())
{
<table class="table table-bordered d-print-table table-striped">
<thead>
<tr class="bg-dark text-white opacity-75 border-bottom">
<th scope="col">Kunde</th>
<th scope="col">Bynavn</th>
<th scope="col">Demo</th>
<th scope="col">Salg</th>
<th scope="col">Note</th>
<th class="text-end" scope="col">sas</th>
<th class="text-end" scope="col">Beløb</th>
<th class="text-center" scope="col"><i class="bi-phone"></i></th>
<th class="text-center" scope="col"><i class="bi-lightning"></i></th>
<th class="text-center" scope="col"><i class="bi-calculator"></i></th>
<th class="text-center" scope="col"><i class="bi-truck"></i></th>
</tr>
}
<tr>
<td class="bg-black opacity-75" colspan="5"></td>
<td class="text-end">Total</td>
<td class="text-end">@Activities.Where(x => x.StatusTypeEnum != "Quote").Sum(x => x.OrderAmount)</td>
<td class="bg-black opacity-75" colspan="4"></td>
</tr>
</tbody>
</table>
@code {
[Parameter]
public List<ReportItemView> Activities { get; set; } = new();
</thead>
<tbody>
@foreach (var activity in ActivityList)
{
<tr>
<td class="align-middle"><a class="btn btn-outline-info text-black d-block" href="/advisor/customers/@activity.Company.CompanyId/orders/@activity.ActivityId">@activity.Company.Name</a></td>
<td class="align-middle">@activity.Company.City</td>
<td class="align-middle">@activity.Demo</td>
<td class="align-middle">@activity.Sales</td>
<td class="align-middle">@activity.OfficeNote</td>
<td class="align-middle text-end">@($"{activity.SasAmount:N2}")</td>
<td class="align-middle text-end">@(activity.StatusTypeEnum == "Quote" ? $"{0:N2}" : $"{activity.OrderAmount:N2}")</td>
<td class="align-middle text-center">
@if (activity.OurRef.Contains("T:"))
{<i style="font-size:1.3em;" class="bi-phone"></i>}
</td>
<td class="align-middle text-center">
@if (activity.Express)
{<i style="font-size:1.3em;" class="bi-lightning"></i>}
</td>
<td class="align-middle text-end">
@if (activity.StatusTypeEnum == "Quote")
{<i style="font-size:1.3em;" class="bi-calculator"></i>}
</td>
<td class="align-middle state">
@if (activity.Lines.Any() && activity.StatusTypeEnum == "Order")
{
<ProcessStateComponent StateClass="@Utils.GetProcessStatus(activity.ProcessStatusEnum)"/>
}
</td>
</tr>
}
<tr>
<td colspan="5" class="bg-dark"></td>
<td class="align-middle text-center">Total</td>
<td class="align-middle text-end">@ActivityList.Where(x => x.StatusTypeEnum == "Order").Sum(x => x.OrderAmount)</td>
<td colspan="4" class="bg-dark"></td>
</tr>
</tbody>
</table>
}
else
{
<div>Ingen data</div>
}

View file

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

View file

@ -58,7 +58,7 @@
@company.City
</td>
<td class="align-middle">
<ActivityButton CompanyId="@company.CompanyId" ActionLink="/customers/$ID$/activities/new"
<ActivityButton CompanyId="@company.CompanyId" ActionLink="/advisor/customers/$ID$/activities/new"
ButtonText="Besøg" ButtonType="primary" Enabled="@company.ValidVat"/>
</td>
</tr>

View file

@ -27,7 +27,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Components
{
public partial class AdvisorCompanyTableComponent
public partial class AdvisorCustomerListComponent
{
[Parameter] public List<CompanyDto> CompanyList { get; set; } = new();
[Parameter] public EventCallback<string> OnDelete { get; set; }
@ -43,7 +43,7 @@ namespace Wonky.Client.Components
private void ViewCustomer(string companyId)
{
Navigator.NavigateTo($"/customers/{companyId}");
Navigator.NavigateTo($"/advisor/customers/{companyId}");
}
private void CallInformationModal(string info)

View file

@ -22,7 +22,7 @@ using Wonky.Client.Services;
namespace Wonky.Client.Components;
public partial class CompanySearchColumnComponent : IDisposable
public partial class CustomerSearchColumnComponent : IDisposable
{
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public UserProfileService ProfileService { get; set; }

View file

@ -20,7 +20,7 @@ using Timer = System.Timers.Timer;
namespace Wonky.Client.Components
{
public partial class CompanySearchPhraseComponent
public partial class CustomerSearchPhraseComponent
{
private Timer InputTimer { get; set; } = new();
private string SearchTerm { get; set; } = "";

View file

@ -21,7 +21,7 @@ using Wonky.Client.Services;
namespace Wonky.Client.Components
{
public partial class CompanySortComponent : IDisposable
public partial class CustomerSortComponent : IDisposable
{
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public UserProfileService ProfileService { get; set; }

View file

@ -18,8 +18,6 @@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
<PageTitle>Innotec Rådgiver</PageTitle>
<AuthorizeView Roles="Advisor">
<div class="bg-dark text-white rounded-2 mb-2 py-2">
<WorkDateComponent />

View file

@ -24,7 +24,7 @@
<div class="card-header">Danmark</div>
<div class="card-body">
<div class="list-group list-group-flush">
<AuthorizeView Roles="Admin">
<AuthorizeView Roles="Admin,Office">
<a class="list-group-item list-group-item-action list-group-item-warning" href="/office/users/advisors/dk">
<i class="bi-activity"></i> Sælgere
</a>
@ -45,7 +45,7 @@
<div class="card-header">Norge</div>
<div class="card-body">
<div class="list-group">
<AuthorizeView Roles="Admin">
<AuthorizeView Roles="Admin,Office">
<a class="list-group-item list-group-item-action list-group-item-warning" href="/office/users/advisors/no">
<i class="bi-activity"></i> Sælgere
</a>
@ -66,7 +66,7 @@
<div class="card-header">Sverige</div>
<div class="card-body">
<div class="list-group">
<AuthorizeView Roles="Admin">
<AuthorizeView Roles="Admin,Office">
<a class="list-group-item list-group-item-action list-group-item-warning" href="/office/users/advisors/se">
<i class="bi-activity"></i> Sælgere
</a>

View file

@ -30,7 +30,7 @@ using Wonky.Entity.Models;
using Wonky.Entity.Views;
namespace Wonky.Client.Components;
public partial class LandingComponentAdmin
public partial class LandingComponentOffice
{
[Inject] public UserProfileService ProfileService { get; set; }

View file

@ -0,0 +1,92 @@
@*
// 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
@* Report activities *@
<table class="table table-striped">
<thead>
<tr class="bg-black opacity-75 text-white">
<th scope="col">Kunde</th>
<th scope="col">Bynavn</th>
<th scope="col">Demo</th>
<th scope="col">Salg</th>
<th scope="col">Note</th>
<th scope="col" class="text-end">sas</th>
<th scope="col" class="text-end">Beløb</th>
<th scope="col" class="text-center">
<i style="font-size:1.3em;" class="bi-phone"></i>
</th>
<th scope="col" class="text-center">
<i class="bi-lightning"></i>
</th>
<th scope="col" class="text-center">
<i class="bi-calculator"></i>
</th>
<th scope="col" class="text-center">
<i class="bi-truck"></i>
</th>
</tr>
</thead>
<tbody>
@foreach (var activity in Activities)
{
<tr>
<td class="text-sm-start">@activity.Company.Name</td>
<td class="text-sm-start">@activity.Company.City</td>
<td class="text-sm-start">@activity.Demo</td>
<td class="text-sm-start">@activity.Sales</td>
<td class="text-sm-start">@activity.OfficeNote</td>
<td class="text-end">@($"{activity.SasAmount:N2}")</td>
<td class="text-center">@(activity.StatusTypeEnum.Contains("Quote") ? $"{0:N2}" : $"{activity.OrderAmount:N2}")</td>
<td class="text-center">
@if (activity.OurRef.Contains("T:"))
{
<i style="font-size:1.5em;" class="bi-phone"></i>
}
</td>
<td class="text-center">
@if (activity.Express)
{
<i style="font-size:1.5em;" class="bi-lightning"></i>
}
</td>
<td class="text-center">
@if (activity.StatusTypeEnum == "Quote")
{
<i style="font-size:1.5em;" class="bi-calculator"></i>
}
</td>
<td class="text-center">
<ProcessStateComponent StateClass="@activity.ProcessStatusEnum"/>
</td>
</tr>
}
<tr>
<td class="bg-black opacity-75" colspan="5"></td>
<td class="text-end">Total</td>
<td class="text-end">@Activities.Where(x => x.StatusTypeEnum != "Quote").Sum(x => x.OrderAmount)</td>
<td class="bg-black opacity-75" colspan="4"></td>
</tr>
</tbody>
</table>
@code {
[Parameter]
public List<ReportItemView> Activities { get; set; } = new();
}

View file

@ -42,7 +42,7 @@
</div>
@foreach (var company in CompanyList)
{
<a class=" list-group-item list-group-item-action" href="/office/customers/@CountryCode/@company.CompanyId/view">
<a class=" list-group-item list-group-item-action" href="/office/customers/@CountryCode/@company.CompanyId/order">
<div class="row align-items-center">
<div class="col-sm-1">
@company.SalesRep

View file

@ -24,7 +24,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Components
{
public partial class CountryCustomerListComponent
public partial class OfficeCountryCustomerListComponent
{
[Parameter] public List<CompanyDto> CompanyList { get; set; } = new();
[Parameter] public string CountryCode { get; set; } = "";

View file

@ -19,7 +19,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Components;
public partial class CountrySalesRepListComponent
public partial class OfficeCountrySalesRepListComponent
{
[Parameter] public List<UserListAdminView> UserList { get; set; } = new();
}

View file

@ -18,7 +18,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Components;
public partial class CountryUserListComponent
public partial class OfficeCountryUserListComponent
{
[Parameter] public List<UserListAdminView> UserList { get; set; } = new();
}

View file

@ -18,7 +18,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Components;
public partial class ReportActivityTableOfficeComponent
public partial class OfficeReportActivityListComponent
{
[Parameter] public List<ReportItemView> ActivityList { get; set; } = new();
[Inject] public NavigationManager Navigator { get; set; }
@ -38,6 +38,6 @@ public partial class ReportActivityTableOfficeComponent
private void ShowOrder(string companyId, string orderId)
{
Navigator.NavigateTo($"office/customers/{companyId}/orders/{orderId}");
Navigator.NavigateTo($"/office/customers/{companyId}/orders/{orderId}");
}
}

View file

@ -18,7 +18,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Components;
public partial class ReportListOfficeComponent
public partial class OfficeReportListComponent
{
[Parameter] public List<SalesReportListView> ReportList { get; set; } = new();
[Parameter] public string UserId { get; set; } = "";

View file

@ -64,7 +64,7 @@
</div>
<div class="col-sm-2 text-center">
<a class="btn btn-outline-dark d-block" style="font-family:monospace;font-size: 14px;"
href="/customers/@quote.Company.CompanyId/quotes/@quote.ActivityId">@quote.ESalesNumber</a>
href="/advisor/customers/@quote.Company.CompanyId/quotes/@quote.ActivityId">@quote.ESalesNumber</a>
</div>
@if (!string.IsNullOrWhiteSpace(quote.OfficeNote))
{

View file

@ -47,7 +47,7 @@
</label>
</td>
<td class="align-middle">
<a class="btn btn-light border-dark" href="/tasks/@task.TaskItemId">
<a class="btn btn-light border-dark" href="/advisor/tasks/@task.TaskItemId">
<i class="oi oi-calendar"></i>
</a>
</td>
@ -64,7 +64,7 @@
<td class="align-middle">
@if (task.TaskTypeEnum is "Recall")
{
<a class="btn btn-light border-dark pe-3 me-2" href="/customers/@task.ReferenceId">
<a class="btn btn-light border-dark pe-3 me-2" href="/advisor/customers/@task.ReferenceId">
<i class="oi oi-pencil"></i>
</a>
}

View file

@ -19,9 +19,9 @@
<AuthorizeView>
<Authorized>
<div class="d-print-none">
<a class="btn btn-outline-light" href="logout" title="Log af" ><i class="bi-lock"></i></a>
<a class="btn btn-outline-light" href="info" title="Information"><i class="bi-question"></i></a>
<a class="btn btn-outline-light" href="preferences" title="Indstillinger"><i class="bi-sliders"></i></a>
<a class="btn btn-outline-light" href="/logout" title="Log af" ><i class="bi-lock"></i></a>
<a class="btn btn-outline-light" href="/info" title="Information"><i class="bi-question"></i></a>
<a class="btn btn-outline-light" href="/preferences" title="Indstillinger"><i class="bi-sliders"></i></a>
</div>
</Authorized>
</AuthorizeView>

View file

@ -14,7 +14,7 @@
</div>
@foreach (var workplace in Workplaces)
{
<a class="list-group-item list-group-item-action" href="/customers/@CompanyId/workplaces/@workplace.WorkplaceId">
<a class="list-group-item list-group-item-action" href="/advisor/customers/@CompanyId/workplaces/@workplace.WorkplaceId">
<div class="row">
<div class="col">
@workplace.Name

View file

@ -18,9 +18,27 @@ using System.Net.Mail;
using Wonky.Entity.DTO;
namespace Wonky.Client.Helpers;
/// <summary>
/// Utilities
/// </summary>
public static class Utils
{
/// <summary>
/// return Country Name from countryCode
/// </summary>
/// <param name="countryCode"></param>
/// <returns></returns>
public static string CountryName(string countryCode)
{
return countryCode.ToLower() switch
{
"dk" => "Danmark",
"no" => "Norge",
"se" => "Sverige",
_ => ""
};
}
/// <summary>
/// Helper to parse querystring
/// </summary>

View file

@ -145,5 +145,4 @@ public class CountryCustomerRepository : ICountryCustomerRepository
Console.WriteLine(content);
return response.IsSuccessStatusCode;
}
}

View file

@ -55,7 +55,7 @@ public class CountryReportRepository : ICountryReportRepository
public async Task<bool> ReportExist(string salesRepId, string workDate)
{
var result = await _client.GetFromJsonAsync<SalesReportClosedView>(
$"{_apiConfig.OfficeReports}/exist/{workDate}");
$"{_apiConfig.OfficeReports}/{salesRepId}/{workDate}/exist");
return result.ReportClosed;
}
/// <summary>

View file

@ -26,13 +26,13 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class BackendAdminSalesRepViewPage : IDisposable
public partial class AdminSalesRepViewPage : IDisposable
{
[Parameter] public string UserId { get; set; } = "";
[Parameter] public string CountryCode { get; set; } = "";
[Inject] public HttpInterceptorService _interceptor { get; set; }
[Inject] public ISystemUserRepository SystemUserRepo { get; set; }
[Inject] public ILogger<BackendAdminSalesRepViewPage> _logger { get; set; }
[Inject] public ILogger<AdminSalesRepViewPage> _logger { get; set; }
[Inject] public NavigationManager _navigator { get; set; }
[Inject] public IToastService _toast { get; set; }
private WebUserInfoView UserInfo { get; set; } = new();
@ -77,6 +77,8 @@ public partial class BackendAdminSalesRepViewPage : IDisposable
_toast.ShowInfo("Sender data til server ...");
await SystemUserRepo.UpdateAdvisor(UserId, _updateInfo);
Working = false;
_toast.ShowInfo("Sælger er opdateret ...");
// _navigator.NavigateTo($"/office/users/advisors/{CountryCode}/{UserId}");
}
private void PwHandleFieldChanged(object sender, FieldChangedEventArgs e)
@ -103,11 +105,13 @@ public partial class BackendAdminSalesRepViewPage : IDisposable
if (Working)
return;
Working = true;
_toast.ShowInfo("Nulstiller adgangskode.");
await SystemUserRepo.ResetUserPassword(UserId, _passwords.NewPassword, _passwords.ConfirmPassword);
_toast.ShowInfo("Password er nulstillet.");
_passwords.NewPassword = "";
_passwords.ConfirmPassword = "";
Working = false;
_toast.ShowInfo("Adgangskode er nulstillet.");
// _navigator.NavigateTo($"/office/users/advisors/{CountryCode}/{UserId}");
}
public void Dispose()
{

View file

@ -18,8 +18,8 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Advisor")]
@page "/price-catalog"
@page "/advisor/price-catalog"
<PageTitle>Innotec Produkt Katalog</PageTitle>
<div class="sticky-top bg-dark rounded-2 px-3">
<div class="row g-3 mb-3">
<div class="col-sm-2">

View file

@ -18,18 +18,20 @@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Advisor")]
@page "/customers/{CompanyId}/activities/new"
@page "/advisor/customers/{CompanyId}/activities/new"
<PageTitle>Rådgiver Opret Aktivetet for @Company.Name</PageTitle>
<div class="row bg-dark text-white rounded-2 mb-2 py-2 align-items-center">
<div class="col">
<WorkDateComponent OnChangedCallback="WorkDateComponentCallback"/>
<WorkDateComponent OnChangedCallback="WorkDateComponentCallback" />
</div>
</div>
@if (!string.IsNullOrWhiteSpace(_company.Blocked))
@if (!string.IsNullOrWhiteSpace(Company.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 '@Company.Blocked'</h4>
</div>
}
<div class="row bg-light border-1 border-dark rounded-3 p-3">
@ -67,7 +69,7 @@ else
<div class="col-md-4">
<InputSelect id="statusType" class="form-select bg-primary text-bg-primary" @bind-Value="@Activity.ActivityStatusEnum">
<option value="noSale">Ingen salg</option>
@if (!string.IsNullOrEmpty(Activity.VatNumber) && !string.IsNullOrWhiteSpace(Activity.Address1) && _company.HasFolded == 0)
@if (!string.IsNullOrEmpty(Activity.VatNumber) && !string.IsNullOrWhiteSpace(Activity.Address1) && Company.HasFolded == 0)
{
@if (DraftProvider.Draft.DraftType == "order")
{
@ -314,7 +316,7 @@ else
</EditForm>
<div class="row mt-5 mb-2">
<div class="col-sm-6">
<a class="btn btn-warning" href="/customers/@_company.CompanyId">Kundekort <i class="bi-arrow-left"></i></a>
<a class="btn btn-warning" href="/advisor/customers/@Company.CompanyId">Kundekort <i class="bi-arrow-left"></i></a>
</div>
<div class="col-sm-4 text-end">
<button type="button" class="btn btn-warning" @onclick="CallConfirmProductCheckModel" disabled="@(PoFormInvalid || Working)"><i class="bi-save-fill"></i> @ButtonText</button>

View file

@ -52,7 +52,7 @@ public partial class AdvisorCreateActivityPage : IDisposable
private SalesItemView SelectedItem { get; set; } = new();
private UserPref UserPrefs { get; set; } = new();
private ActivityDto Activity { get; set; } = new();
private CompanyDto _company = new();
private CompanyDto Company = new();
private EditContext? ActivityContext { get; set; }
private bool PoFormInvalid { get; set; } = true;
private bool ShowItem { get; set; }
@ -95,42 +95,42 @@ public partial class AdvisorCreateActivityPage : IDisposable
// User Info
ThisUserInfo = await Storage.GetItemAsync<UserInfoView>("_xu");
// Fetch Customer from http
_company = await CompanyRepo.GetCompanyById(CompanyId);
if (_company.HasFolded == 1)
Company = await CompanyRepo.GetCompanyById(CompanyId);
if (Company.HasFolded == 1)
// Company has shutdown activities
Activity.OrderMessage = "BEMÆRK: CVR nummer er ophørt.";
// variable to validate if customer needs phone number update
OldPhone = _company.Phone;
if (string.IsNullOrWhiteSpace(_company.Phone)
&& !string.IsNullOrWhiteSpace(_company.Account)
&& _company.Account != "NY" && _company.Account.Length > 7)
OldPhone = Company.Phone;
if (string.IsNullOrWhiteSpace(Company.Phone)
&& !string.IsNullOrWhiteSpace(Company.Account)
&& Company.Account != "NY" && Company.Account.Length > 7)
{
_company.Phone = _company.Account[..8];
Company.Phone = Company.Account[..8];
}
// Populate base activity information
Activity.BcId = _company.BcId;
Activity.BcId = Company.BcId;
Activity.ActivityStatusEnum = "noSale";
Activity.VisitTypeEnum = _company.Account is "" or "NY" ? "new" : "recall";
Activity.CompanyId = _company.CompanyId;
Activity.VisitTypeEnum = Company.Account is "" or "NY" ? "new" : "recall";
Activity.CompanyId = Company.CompanyId;
Activity.SalesRepId = ThisUserInfo.Id;
Activity.SalesRep = ThisUserInfo.Advisor;
Activity.CountryCode = ThisUserInfo.CountryCode;
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.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;
// Initialize date variable
SelectedDate = string.IsNullOrWhiteSpace(UserPrefs.WorkDate) ? DateTime.Now : DateTime.Parse(UserPrefs.WorkDate);
// raise flag if report is closed
@ -157,8 +157,8 @@ public partial class AdvisorCreateActivityPage : IDisposable
private async Task CallConfirmProductCheckModel()
{
// check if new account
if (string.IsNullOrWhiteSpace(_company.Account)
|| _company.Account.ToLower() == "ny"
if (string.IsNullOrWhiteSpace(Company.Account)
|| Company.Account.ToLower() == "ny"
|| Activity.ActivityStatusEnum.ToLower() == "quote")
{
// proceed to create activity - as there is no product check to be done
@ -182,7 +182,7 @@ public partial class AdvisorCreateActivityPage : IDisposable
// product inventory has not been updated
// send rpc call to sync ERP to CRM
Toast.ShowInfo("Vent mens data synkroniseres ...", "ERP til CRM ...");
var ts = await HistoryRepo.InvoiceErpToCrmRpc(CompanyId, _company.HistorySync);
var ts = await HistoryRepo.InvoiceErpToCrmRpc(CompanyId, Company.HistorySync);
while (string.IsNullOrWhiteSpace(ts))
await Task.Delay(500);
// save pDate
@ -308,7 +308,7 @@ public partial class AdvisorCreateActivityPage : IDisposable
Toast.ShowError("Ved bestilling skal der være en eller flere linjer i kladden.");
return;
// phone number is required if first time customer
case "order" when _company.Account is "NY" or "" && string.IsNullOrWhiteSpace(Activity.Phone):
case "order" when Company.Account is "NY" or "" && string.IsNullOrWhiteSpace(Activity.Phone):
Toast.ShowError("Ved bestilling til ny kunde skal telefon nummer angives.");
return;
// verify email address is a valid address
@ -324,8 +324,8 @@ public partial class AdvisorCreateActivityPage : IDisposable
// check if phone number need to be updated
if (OldPhone != Activity.Phone)
{
_company.Phone = Activity.Phone;
await CompanyRepo.UpdateErpData(_company.CompanyId, _company);
Company.Phone = Activity.Phone;
await CompanyRepo.UpdateErpData(Company.CompanyId, Company);
}
// begin assembling activity
Activity.ActivityDate = $"{SelectedDate:yyyy-MM-dd}";
@ -370,7 +370,7 @@ public partial class AdvisorCreateActivityPage : IDisposable
Toast.ShowSuccess($"{result.Message}",
DraftProvider.Draft.Items.Count == 0 ? "Besøg er oprettet" : "Bestilling/Tilbud er oprettet");
await DeleteDraft();
Navigator.NavigateTo($"/customers");
Navigator.NavigateTo($"/advisor/customers");
return;
}
// lower working flag

View file

@ -15,12 +15,13 @@
//
*@
@page "/customers/new"
@page "/advisor/customers/new"
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@using System.Xml
@attribute [Authorize(Roles = "Advisor")]
<PageTitle>Rådgiver Opret Kunde</PageTitle>
<h2>Opret kunde</h2>
<EditForm EditContext="CompanyContext" OnValidSubmit="SubmitCompanyForm">

View file

@ -136,7 +136,7 @@ namespace Wonky.Client.Pages
/// <param name="regInfo"></param>
private void SelectCompanyCallback(VirkRegInfo regInfo)
{
Logger.LogDebug($"CrmCompanyView => SelectCompanyCallback => {JsonSerializer.Serialize(regInfo)}");
Logger.LogDebug("CrmCompanyView => SelectCompanyCallback => {}", JsonSerializer.Serialize(regInfo));
// this can be removed in favor of the new data returned from updating the VatNumber
RegState = regInfo.States[0].State.ToLower() == "normal" ? "the-good" : "the-dead";
@ -177,7 +177,7 @@ namespace Wonky.Client.Pages
if (!string.IsNullOrWhiteSpace(newId))
{
Toaster.ShowSuccess($"'{Company.Name}' er oprettet i CRM.");
Navigator.NavigateTo($"/customers/{newId}");
Navigator.NavigateTo($"/advisor/customers/{newId}");
}
else
{

View file

@ -18,7 +18,9 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Advisor")]
@page "/customers/{CompanyId}/activities"
@page "/advisor/customers/{CompanyId}/activities"
<PageTitle>Rådgiver Aktiviteter for @Company.Name</PageTitle>
@if (!string.IsNullOrWhiteSpace(Company.Name))
{
@ -27,10 +29,10 @@
<h4 class="pt-1">@Company.Name</h4>
</div>
<div class="col-sm-3 align-content-end">
<a class="btn btn-primary d-block" href="/customers/@Company.CompanyId"><i class="bi-arrow-right"></i> Kundekort</a>
<a class="btn btn-primary d-block" href="/advisor/customers/@Company.CompanyId"><i class="bi-arrow-right"></i> Kundekort</a>
</div>
<div class="col-sm-3 align-content-end">
<a class="btn btn-primary d-block" href="/customers/@Company.CompanyId/activities/new"><i class="bi-arrow-right"></i> Besøg</a>
<a class="btn btn-primary d-block" href="/advisor/customers/@Company.CompanyId/activities/new"><i class="bi-arrow-right"></i> Besøg</a>
</div>
</div>

View file

@ -17,18 +17,18 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@page "/customers/{CompanyId}/h/i"
@page "/advisor/customers/{CompanyId}/h/i"
@attribute [Authorize(Roles = "Advisor")]
<PageTitle>Produkt oversigt for @Company.Name</PageTitle>
<div class="row pt-2 pb-1 rounded-2 bg-dark text-white">
<div class="col-sm-6">
<h4 class="pt-1">@Company.Name</h4>
</div>
<div class="col-sm-3 align-content-end">
<a class="btn btn-primary d-block" href="/customers/@CompanyId"><i class="bi-arrow-left"></i> Kundekort</a>
<a class="btn btn-primary d-block" href="/advisor/customers/@CompanyId"><i class="bi-arrow-left"></i> Kundekort</a>
</div>
<div class="col-sm-3 align-content-end">
<a class="btn btn-primary d-block" href="/customers/@CompanyId/activities/new"><i class="bi-arrow-right"></i> Nyt Besøg</a>
<a class="btn btn-primary d-block" href="/advisor/customers/@CompanyId/activities/new"><i class="bi-arrow-right"></i> Nyt Besøg</a>
</div>
</div>

View file

@ -16,9 +16,9 @@
*@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@page "/customers/{CompanyId}/invoices"
@page "/advisor/customers/{CompanyId}/invoices"
@attribute [Authorize(Roles = "Advisor")]
<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">
@ -26,10 +26,10 @@
<h4 class="pt-1">@Company.Name</h4>
</div>
<div class="col-sm-3 align-content-end">
<a class="btn btn-primary d-block" href="/customers/@Company.CompanyId"><i class="bi-arrow-right"></i> Kundekort</a>
<a class="btn btn-primary d-block" href="/advisor/customers/@Company.CompanyId"><i class="bi-arrow-right"></i> Kundekort</a>
</div>
<div class="col-sm-3 align-content-end">
<a class="btn btn-primary d-block" href="/customers/@Company.CompanyId/activities/new"><i class="bi-arrow-right"></i> Besøg</a>
<a class="btn btn-primary d-block" href="/advisor/customers/@Company.CompanyId/activities/new"><i class="bi-arrow-right"></i> Besøg</a>
</div>
</div>
<CustomerInvoiceListComponent OnShowInvoice="CallInvoiceModal" CompanyId="@_companyId" InvoiceList="@CompanyInvoices.Invoices"/>

View file

@ -17,19 +17,19 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@page "/customers"
@page "/advisor/customers"
@attribute [Authorize(Roles = "Advisor")]
<PageTitle>Kunde oversigt</PageTitle>
<div class="sticky-top bg-dark text-light rounded-2 px-3">
<div class="row g-3">
<div class="col-sm-2">
<CompanySearchColumnComponent OnChanged="SetSearchCol" />
<CustomerSearchColumnComponent OnChanged="SetSearchCol" />
</div>
<div class="col-sm-6">
<CompanySearchPhraseComponent OnChanged="SetSearchPhrase" />
<CustomerSearchPhraseComponent OnChanged="SetSearchPhrase" />
</div>
<div class="col-sm-2">
<CompanySortComponent OnChanged="SetSortCol" />
<CustomerSortComponent OnChanged="SetSortCol" />
</div>
<div class="col-sm-2">
<PageSizeComponent OnChanged="SetPageSize" />
@ -44,12 +44,12 @@
<PaginationComponent MetaData="PageData" Spread="2" SelectedPage="SelectedPage"/>
</div>
<div class="col-sm-2 text-end">
<a class="btn btn-success text-nowrap" href="/customers/new">Opret kunde <i class="bi-plus"></i></a>
<a class="btn btn-success text-nowrap" href="/advisor/customers/new">Opret kunde <i class="bi-plus"></i></a>
</div>
</div>
</div>
<AdvisorCompanyTableComponent CompanyList="Companies" OnDelete="DeleteCompany" />
<AdvisorCustomerListComponent CompanyList="Companies" OnDelete="DeleteCompany" />
@if (Working)
{

View file

@ -17,9 +17,9 @@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Admin,Advisor,Warehouse")]
@page "/office/customers/{CompanyId}/orders/{OrderId}"
@attribute [Authorize(Roles = "Advisor")]
@page "/advisor/customers/{CompanyId}/orders/{OrderId}"
<PageTitle>@_reportItem.ESalesNumber - @_reportItem.Company.Name</PageTitle>
<table class="table table-sm table-striped d-print-table">
<thead>
<tr>
@ -29,23 +29,6 @@
<div id="watermark">
<i class="bi-lightning-charge text-dark" style="font-size: 11rem;"></i>
</div>
@if (_reportItem.ProcessStatusEnum == "None")
{
<AuthorizeView Roles="Admin,Office,Warehouse">
<Authorized>
<div class="d-print-none">
<div class="row">
<div class="col-sm-1">
<button type="button" class="btn btn-warning d-block" onclick="window.print();">PRINT</button>
</div>
<div class="col-sm-5">
<button type="button" class="btn btn-warning d-block" @onclick="SetExpressState" disabled="@_isNotified">Kvitter for modtagelse</button>
</div>
</div>
</div>
</Authorized>
</AuthorizeView>
}
}
<div class="bg-light text-dark border border-1 rounded-3 pt-3 mb-2">
<h2 class="fw-bold text-center">@_reportItem.Company.Name</h2>

View file

@ -39,7 +39,7 @@ public partial class AdvisorCustomerOrderViewPage : IDisposable
[Inject] public ISystemSendMailService MailService { get; set; }
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public ISystemUserRepository SystemUserRepo { get; set; }
[Inject] public ILogger<AdvisorCustomerOrderViewPage> Logger { get; set; }
[Inject] public ILogger<OfficeCustomerOrderViewPage> Logger { get; set; }
[Inject] public IToastService Toast { get; set; }
private ReportItemView _reportItem { get; set; } = new();
private bool _isNotified { get; set; }

View file

@ -19,8 +19,8 @@
@using Microsoft.AspNetCore.Components
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Advisor")]
@page "/customers/{CompanyId}"
@page "/advisor/customers/{CompanyId}"
<PageTitle>Kundekort for @Company.Name</PageTitle>
@if (!string.IsNullOrWhiteSpace(Company.Account))
{
@ -128,13 +128,13 @@
@* activity buttons *@
<div class="row mt-3 mb-3">
<div class="col-sm-3">
<a class="btn btn-danger d-block" href="/customers/@Company.CompanyId/invoices">Faktura</a>
<a class="btn btn-danger d-block" href="/advisor/customers/@Company.CompanyId/invoices">Faktura</a>
</div>
<div class="col-sm-3">
<a class="btn btn-warning d-block" href="/customers/@Company.CompanyId/activities">Tidl. Besøg</a>
<a class="btn btn-warning d-block" href="/advisor/customers/@Company.CompanyId/activities">Tidl. Besøg</a>
</div>
<div class="col-sm-3">
<a class="btn btn-success d-block" href="/customers/@Company.CompanyId/h/i">Produkter</a>
<a class="btn btn-success d-block" href="/advisor/customers/@Company.CompanyId/h/i">Produkter</a>
</div>
<div class="col-sm-3">
<ActivityButton ActionLink="@ActionLink"

View file

@ -115,7 +115,7 @@ public partial class AdvisorCustomerViewPage : IDisposable
// display urgency of next visit
VisitState = Utils.GetVisitState($"{NextVisit:yyyy-MM-dd}");
// action link passed to activity button component
ActionLink = $"/customers/{CompanyId}/activities/new"; // used when drawing visit button
ActionLink = $"/advisor/customers/{CompanyId}/activities/new"; // used when drawing visit button
// handle company out of business case
if(Company.HasFolded == 1)
{

View file

@ -18,8 +18,8 @@
@using Wonky.Client.Models
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Advisor")]
@page "/open-quotes"
@page "/advisor/open-quotes"
<PageTitle>Aftaler og Tilbud - Oversigt</PageTitle>
<div class="row g-3 align-items-center">
<div class="col-sm-8">
<h2>Aftaler og Tilbud</h2>

View file

@ -19,7 +19,9 @@
@using Wonky.Client.Components
@using Wonky.Entity.Views
@attribute [Authorize(Roles = "Advisor")]
@page "/sales-reports/new"
@page "/advisor/sales-reports/new"
<PageTitle>Opret Dagsrapport for @_workDate</PageTitle>
@* report header *@
<div class="row sticky-top bg-dark text-white rounded-2 mb-2 py-2 align-items-center">

View file

@ -70,7 +70,7 @@ public partial class AdvisorReportCreatePage : IDisposable
_workDate = DateTime.Parse(Prefs.WorkDate);
if(await AdvisorReportRepo.ReportExist(Prefs.WorkDate))
Navigator.NavigateTo($"/sales-reports/view/{_workDate:yyyy-MM-dd}");
Navigator.NavigateTo($"/advisor/sales-reports/view/{_workDate:yyyy-MM-dd}");
BeginLeave = _workDate;
EndLeave = _workDate;
@ -137,7 +137,7 @@ public partial class AdvisorReportCreatePage : IDisposable
await ProfileService.SetKmMorning(0);
// reset date confirmed
await ProfileService.SetDateConfirmed(false);
Navigator.NavigateTo($"/sales-reports/view/{_workDate:yyyy-MM-dd}");
Navigator.NavigateTo($"/advisor/sales-reports/view/{_workDate:yyyy-MM-dd}");
}
/// <summary>
/// Submit report
@ -252,7 +252,7 @@ public partial class AdvisorReportCreatePage : IDisposable
var data = await AdvisorReportRepo.InitializeReportData($"{_workDate:yyyy-MM-dd}");
if(data.ReportClosed)
Navigator.NavigateTo($"/sales-reports/view/{_workDate:yyyy-MM-dd}");
Navigator.NavigateTo($"/advisor/sales-reports/view/{_workDate:yyyy-MM-dd}");
Report.Figures = data.ReportData;
InitialValues = data.ReportData;

View file

@ -18,8 +18,8 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Advisor")]
@page "/sales-reports"
@page "/advisor/sales-reports"
<PageTitle>Rapport Arkiv</PageTitle>
<div class="card">
<div class="card-header bg-dark text-white">
<h3>Rapport Arkiv</h3>

View file

@ -49,7 +49,7 @@ public partial class AdvisorReportListPage : IDisposable
private void ShowThisReport(string reportDate)
{
Logger.LogDebug("CrmReportListPage => ShowThisReport <= {}", reportDate);
Navigator.NavigateTo($"/sales-reports/view/{reportDate}");
Navigator.NavigateTo($"/advisor/sales-reports/view/{reportDate}");
}
public void Dispose()

View file

@ -19,8 +19,8 @@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Models
@attribute [Authorize(Roles = "Advisor,Admin")]
@page "/sales-reports/view/{ReportDate}"
@page "/advisor/sales-reports/view/{ReportDate}"
<PageTitle>@Report.ReportData.Name</PageTitle>
<div class="row bg-dark text-white rounded-2 mb-2 py-2 align-items-center d-print-none">
<div class="col-sm-6">
<WorkDateComponent OnChangedCallback="FetchReport"/>
@ -51,7 +51,7 @@
<ReportDistanceLedgerComponent ReportData="Report.ReportData"/>
</div>
</div>
<ReportActivityTableOfficeComponent ActivityList="Report.ReportItems"/>
<OfficeReportActivityListComponent ActivityList="Report.ReportItems"/>
<ReportActivityLedgerComponent ReportData="Report.ReportData"/>
}
else

View file

@ -85,7 +85,7 @@ public partial class AdvisorReportViewPage : IDisposable
}
// ensure the browser address bar contains the correct link
Navigator.NavigateTo($"/sales-reports/view/{workDate}", false, true);
Navigator.NavigateTo($"/advisor/sales-reports/view/{workDate}", false, true);
// return if we are already at it
if (Working)

View file

@ -18,8 +18,8 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Advisor")]
@page "/task-items"
@page "/advisor/task-items"
<PageTitle>Opgave Oversigt</PageTitle>
<div class="card">
<div class="card-header">
<div class="row mb-1 align-items-center">
@ -30,7 +30,7 @@
<WorkDateComponent OnChangedCallback="GetTaskItems" />
</div>
<div class="col-md-6">
<a class="btn btn-primary" href="/task-items/new">NY OPGAVE</a>
<a class="btn btn-primary" href="/advisor/task-items/new">NY OPGAVE</a>
</div>
</div>
</div>

View file

@ -18,8 +18,8 @@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Advisor")]
@page "/tasks/{TaskItemId}"
@page "/advisor/tasks/{TaskItemId}"
<PageTitle>Opgave kort</PageTitle>
<div class="card">
<div class="card-header">
<h3>Opgave</h3>

View file

@ -18,8 +18,8 @@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Advisor")]
@page "/activity-today"
@page "/advisor/activity-today"
<PageTitle>Aktiviteter for @($"{SelectedDate:yyyy-MM-dd}")</PageTitle>
<div class="row bg-dark text-white rounded-2 mb-2 py-2 align-items-center">
<div class="col-sm-7">
<WorkDateComponent OnChangedCallback="GetActivities"/>
@ -30,17 +30,17 @@
<div class="col-sm-2 text-end">
@if (ReportExist)
{
<a class="btn btn-info" href="/sales-reports/view/@($"{SelectedDate:yyyy-MM-dd}")">Rapport <i style="font-size: 1.2em;" class="bi-info-lg"></i></a>
<a class="btn btn-info" href="/advisor/sales-reports/view/@($"{SelectedDate:yyyy-MM-dd}")">Rapport <i style="font-size: 1.2em;" class="bi-info-lg"></i></a>
}
else
{
<a class="btn btn-primary" href="/sales-reports/new">Rapport <i style="font-size:1.2em;" class="bi-plus-lg"></i></a>
<a class="btn btn-primary" href="/advisor/sales-reports/new">Rapport <i style="font-size:1.2em;" class="bi-plus-lg"></i></a>
}
</div>
</div>
@if (ReportStatusView.ReportItems.Any())
{
<ActivityListComponent ActivityList="ReportStatusView.ReportItems"/>
<AdvisorActivityListComponent ActivityList="ReportStatusView.ReportItems"/>
}
@if (Working)
{

View file

@ -19,9 +19,10 @@
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Admin,Advisor,Warehouse")]
@page "/customers/{CompanyId}/orders/{OrderId}"
@page "/customers/{CompanyId}/quotes/{OrderId}"
@page "/advisor/customers/{CompanyId}/orders/{OrderId}"
@page "/advisor/customers/{CompanyId}/quotes/{OrderId}"
<PageTitle>@ReportItem.Company.Name @ReportItem.OrderDate</PageTitle>
@* <ReportItemComponent ReportItem="@_item" /> *@
<table class="table table-sm table-striped d-print-table">
@ -129,7 +130,7 @@
</tbody>
</table>
@* Office Note *@
@if (ReportItem.ProcessStatusEnum == "None" && !ReportItem.Express && AllowOfficeNoteUpdate())
@if (ReportItem is { ProcessStatusEnum: "None",Express: false } && AllowOfficeNoteUpdate())
{
<div class="alert border border-1 border-primary">
<EditForm EditContext="NoteContext">

View file

@ -70,7 +70,7 @@ public partial class AdvisorViewActivityPage : IDisposable
Logger.LogDebug("OfficeNote => \n {}", JsonSerializer.Serialize(Note));
await AdvisorActivityRepo.UpdateOfficeNote(Note);
Toaster.ShowInfo($"{ReportItem.ESalesNumber} - notat opdateret");
Navigator.NavigateTo("/activity-today");
Navigator.NavigateTo("/advisor/activity-today");
}
private bool AllowOfficeNoteUpdate()

View file

@ -18,8 +18,9 @@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Advisor")]
@page "/customers/{CompanyId}/workplaces/{WorkplaceId}/documents"
@page "/advisor/customers/{CompanyId}/workplaces/{WorkplaceId}/documents"
<PageTitle>Dokumenter for Arbejdssted</PageTitle>
<h2>Dokumenter</h2>
@if (Working)

View file

@ -18,11 +18,11 @@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Advisor")]
@page "/customers/{CompanyId}/workplaces"
@page "/advisor/customers/{CompanyId}/workplaces"
<PageTitle>@Company.Name arbejdssteder</PageTitle>
<div class="row bg-light border border-1 rounded-2">
<div class="col">
<h2>@_company.Name</h2>
<h2>@Company.Name</h2>
</div>
</div>
<div class="row">

View file

@ -31,14 +31,14 @@ public partial class AdvisorWorkplaceListPage : IDisposable
[Inject] public IAdvisorCustomerRepository _companyRepo { get; set; }
[Inject] public HttpInterceptorService _interceptor { get; set; }
private List<WorkplaceListView> _workplaces { get; set; } = new();
private CompanyDto _company { get; set; } = new();
private CompanyDto Company { get; set; } = new();
private bool Working { get; set; } = true;
protected override async Task OnParametersSetAsync()
{
_interceptor.RegisterEvent();
_interceptor.RegisterBeforeSendEvent();
_company = await _companyRepo.GetCompanyById(CompanyId);
Company = await _companyRepo.GetCompanyById(CompanyId);
Working = false;
}

View file

@ -19,13 +19,13 @@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Advisor")]
@page "/customers/{CompanyId}/workplaces/{WorkplaceId}"
@page "/advisor/customers/{CompanyId}/workplaces/{WorkplaceId}"
<PageTitle>@Workplace.CompanyName - @Workplace.Name</PageTitle>
<div class="card">
<div class="card-header">
<div class="card-title">
<h2>@_workplace.CompanyName</h2>
<h3>@_workplace.Name @(!string.IsNullOrWhiteSpace(_workplace.Description) ? $"- {_workplace.Description}" : "")</h3>
<h2>@Workplace.CompanyName</h2>
<h3>@Workplace.Name @(!string.IsNullOrWhiteSpace(Workplace.Description) ? $"- {Workplace.Description}" : "")</h3>
</div>
</div>
<div class="card-body">
@ -44,13 +44,13 @@
<tr>
<td class="align-middle">Navn</td>
<td class="align-middle">
<InputText id="name" class="form-control" @bind-Value="_workplace.Name"/>
<ValidationMessage For="@(() => _workplace.Name)"></ValidationMessage>
<InputText id="name" class="form-control" @bind-Value="Workplace.Name"/>
<ValidationMessage For="@(() => Workplace.Name)"></ValidationMessage>
</td>
<td class="align-middle">Beskrivelse</td>
<td class="align-middle">
<InputText id="description" class="form-control" @bind-Value="_workplace.Description"/>
<ValidationMessage For="@(() => _workplace.Description)"></ValidationMessage>
<InputText id="description" class="form-control" @bind-Value="Workplace.Description"/>
<ValidationMessage For="@(() => Workplace.Description)"></ValidationMessage>
</td>
</tr>
<tr>
@ -59,48 +59,48 @@
<tr>
<td class="align-middle">Produkter</td>
<td class="align-middle">
<InputText id="productStorage" class="form-control" @bind-Value="_workplace.ProductStorage"/>
<ValidationMessage For="@(() => _workplace.ProductStorage)"></ValidationMessage>
<InputText id="productStorage" class="form-control" @bind-Value="Workplace.ProductStorage"/>
<ValidationMessage For="@(() => Workplace.ProductStorage)"></ValidationMessage>
</td>
<td class="align-middle" colspan="2"></td>
</tr>
<tr>
<td class="align-middle">Masker</td>
<td class="align-middle">
<InputText id="maskStorage" class="form-control" @bind-Value="_workplace.MaskStorage"/>
<ValidationMessage For="@(() => _workplace.MaskStorage)"></ValidationMessage>
<InputText id="maskStorage" class="form-control" @bind-Value="Workplace.MaskStorage"/>
<ValidationMessage For="@(() => Workplace.MaskStorage)"></ValidationMessage>
</td>
<td class="align-middle">Øjenskylleflaske</td>
<td class="align-middle">
<InputText id="eyeCleanerLocation" class="form-control" @bind-Value="_workplace.EyeCleanerLocation"/>
<ValidationMessage For="@(() => _workplace.EyeCleanerLocation)"></ValidationMessage>
<InputText id="eyeCleanerLocation" class="form-control" @bind-Value="Workplace.EyeCleanerLocation"/>
<ValidationMessage For="@(() => Workplace.EyeCleanerLocation)"></ValidationMessage>
</td>
</tr>
<tr>
<td class="align-middle">Handsker</td>
<td class="align-middle">
<InputText id="glovesStorage" class="form-control" @bind-Value="_workplace.GlovesStorage"/>
<ValidationMessage For="@(() => _workplace.GlovesStorage)"></ValidationMessage>
<InputText id="glovesStorage" class="form-control" @bind-Value="Workplace.GlovesStorage"/>
<ValidationMessage For="@(() => Workplace.GlovesStorage)"></ValidationMessage>
</td>
<td class="align-middle">Førstehjælp</td>
<td class="align-middle">
<InputText id="firstAidStorage" class="form-control" @bind-Value="_workplace.FirstAidStorage"/>
<ValidationMessage For="@(() => _workplace.FirstAidStorage)"></ValidationMessage>
<InputText id="firstAidStorage" class="form-control" @bind-Value="Workplace.FirstAidStorage"/>
<ValidationMessage For="@(() => Workplace.FirstAidStorage)"></ValidationMessage>
</td>
</tr>
<tr>
<td class="align-middle">Sikkerhedsbriller</td>
<td class="align-middle">
<InputText id="gogglesStorage" class="form-control" @bind-Value="_workplace.GogglesStorage"/>
<ValidationMessage For="@(() => _workplace.GogglesStorage)"></ValidationMessage>
<InputText id="gogglesStorage" class="form-control" @bind-Value="Workplace.GogglesStorage"/>
<ValidationMessage For="@(() => Workplace.GogglesStorage)"></ValidationMessage>
</td>
<td class="align-middle" colspan="2"></td>
</tr>
<tr>
<td class="align-middle">Affald</td>
<td class="align-middle">
<InputText id="masteDeposit" class="form-control" @bind-Value="_workplace.WasteDeposit"/>
<ValidationMessage For="@(() => _workplace.WasteDeposit)"></ValidationMessage>
<InputText id="wasteDeposit" class="form-control" @bind-Value="Workplace.WasteDeposit"/>
<ValidationMessage For="@(() => Workplace.WasteDeposit)"></ValidationMessage>
</td>
<td class="align-middle" colspan="2"></td>
</tr>
@ -114,7 +114,7 @@
<button type="submit" class="btn btn-success">Gem</button>
</div>
<div class="col-md-4">
<a class="btn btn-primary" href="/customers/@CompanyId/workplaces/@WorkplaceId/documents">Dokumenter</a>
<a class="btn btn-primary" href="/advisor/customers/@CompanyId/workplaces/@WorkplaceId/documents">Dokumenter</a>
</div>
</div>
</EditForm>

View file

@ -33,7 +33,7 @@ public partial class AdvisorWorkplaceViewPage : IDisposable
[Inject] public IAdvisorCustomerRepository _companyRepo { get; set; }
[Inject] public HttpInterceptorService _interceptor { get; set; }
[Inject] public NavigationManager _navigator { get; set; }
private WorkplaceDto _workplace { get; set; } = new();
private WorkplaceDto Workplace { get; set; } = new();
private EditContext _editContext { get; set; }
private bool Working { get; set; } = true;
@ -42,27 +42,27 @@ public partial class AdvisorWorkplaceViewPage : IDisposable
_interceptor.RegisterEvent();
_interceptor.RegisterBeforeSendEvent();
_workplace = await WorkplaceCrmRepo.GetWorkplace(CompanyId, WorkplaceId);
Workplace = await WorkplaceCrmRepo.GetWorkplace(CompanyId, WorkplaceId);
Working = false;
}
protected override void OnInitialized()
{
_editContext = new EditContext(_workplace);
_editContext = new EditContext(Workplace);
}
private async Task SubmitUpdate()
{
Working = true;
await WorkplaceCrmRepo.UpdateWorkplace(CompanyId, _workplace);
await WorkplaceCrmRepo.UpdateWorkplace(CompanyId, Workplace);
Working = false;
}
private async Task DeleteWorkplace()
{
Working = true;
await WorkplaceCrmRepo.DeleteWorkplace(CompanyId, _workplace.WorkplaceId);
_navigator.NavigateTo($"/customers/{CompanyId}/workplaces");
await WorkplaceCrmRepo.DeleteWorkplace(CompanyId, Workplace.WorkplaceId);
_navigator.NavigateTo($"/advisor/customers/{CompanyId}/workplaces");
}
public void Dispose()

View file

@ -16,6 +16,7 @@
*@
@page "/401"
<PageTitle>Fejl 401</PageTitle>
<div class="card page401">
<div class="card-header">
<div class="row">

View file

@ -17,6 +17,7 @@
@page "/page404"
@page "/404"
<PageTitle>Fejl 404</PageTitle>
<div class="card page404">
<div class="card-header">
<div class="row">

View file

@ -21,7 +21,7 @@ public partial class ErrorPage404
{
[Inject] public NavigationManager NavigationManager { get; set; }
public void NavigateToHome()
private void NavigateToHome()
{
// preserving the uri for later navigation
var currUri = NavigationManager.Uri;

View file

@ -17,6 +17,7 @@
@page "/error"
@page "/500"
<PageTitle>Fejl 500</PageTitle>
<div class="card page500">
<div class="card-header">
<div class="row">

View file

@ -16,6 +16,7 @@
*@
@page "/report-error/{errorCode:int}/{errorDescription}"
<PageTitle>Fejlrapport</PageTitle>
<h1>@ErrorCode</h1>
<p>@ErrorDescription</p>
<div class="row">

View file

@ -17,17 +17,17 @@
@using Wonky.Client.Components;
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Advisor,Admin,Office,Supervisor,Warehouse")]
@attribute [Authorize(Roles = "Admin,Advisor,Office,Supervisor,Warehouse")]
@page "/"
@page "/index"
@page "/home"
<PageTitle>Innotec Danmark A/S</PageTitle>
<AuthorizeView Roles="Advisor">
<LandingComponentAdvisor />
</AuthorizeView>
<AuthorizeView Roles="Admin,Warehouse">
<LandingComponentAdmin />
<AuthorizeView Roles="Admin,Office,Warehouse">
<LandingComponentOffice />
</AuthorizeView>
@code{

View file

@ -20,8 +20,8 @@
@using Wonky.Entity.Configuration
@using Microsoft.AspNetCore.Authorization
@page "/info"
@attribute [Authorize(Roles = "Advisor,Admin,Office,Warehouse")]
<PageTitle>App Information</PageTitle>
@attribute [Authorize(Roles = "Admin,Advisor,Office,Supervisor,Warehouse")]
<div class="row mb-2">
<div class="col">
<div class="text-center">

View file

@ -17,7 +17,7 @@
@using Wonky.Client.Components
@page "/login/{returnUrl?}"
<PageTitle>App Login</PageTitle>
<section class=" text-center text-lg-start">
@if (ShowAuthError)
{

View file

@ -45,7 +45,7 @@ public partial class Login
}
else
{
Logger.LogInformation($"returnUrl={ReturnUrl}");
Logger.LogInformation("returnUrl={}", ReturnUrl);
var returnUrl = string.IsNullOrWhiteSpace(ReturnUrl) ? "/" : ReturnUrl;
NavigationManager.NavigateTo(returnUrl);
}

View file

@ -17,9 +17,9 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Warehouse")]
@attribute [Authorize(Roles = "Admin,Office,Warehouse")]
@page "/office/catalog/{CountryCode}"
<PageTitle>Produkt Katalog @CountryCode</PageTitle>
<div class="sticky-top bg-dark rounded-2 px-3">
<div class="row g-3 mb-3">

View file

@ -23,7 +23,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class CountryCatalogPage : IDisposable
public partial class OfficeCountryCatalogPage : IDisposable
{
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public ICountryCatalogRepository Catalog { get; set; }

View file

@ -15,9 +15,12 @@
//
*@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Warehouse")]
@page "/office/customers/{CountryCode}/{CompanyId}/view"
@attribute [Authorize(Roles = "Admin,Office,Warehouse")]
@page "/office/customers/{CountryCode}/{CompanyId}/order"
<PageTitle>Telefon Ordre - @Customer.Name - @Customer.Account</PageTitle>
<div class="row bg-dark text-white rounded-2 mb-2 py-2 align-items-center">
<div class="col">
@ -25,61 +28,47 @@
</div>
</div>
<div class="row bg-light border-1 border-dark rounded-3 p-3">
<div class="col">
<h3>@Activity.Name - @Activity.Account</h3>
<div class="row bg-light border-2 border-dark rounded-3 p-3">
<div class="col-sm-12">
<h3>@Customer.Name - @Customer.Account</h3>
</div>
</div>
@if (ReportClosed)
{
<div class="row">
<div class="col">
<h3>Der kan ikke oprettes bestilling når der findes rapport for @SelectedDate.ToShortDateString()</h3>
</div>
</div>
}
else
{
<EditForm EditContext="ActivityContext">
<EditForm EditContext="ActivityContext">
<DataAnnotationsValidator/>
<div class="row mb-1">
<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 class="row mb-1 g-3">
<label for="yourRef" class="col-sm-2 col-md-2 col-form-label">Indkøber</label>
<div class="col-sm-10 col-md-4">
<InputText id="yourRef" class="form-control" @bind-Value="Activity.YourRef"/>
<ValidationMessage For="@(() => Activity.YourRef)"></ValidationMessage>
</div>
</div>
<div class="row mb-1">
<label for="referenceNumber" class="col-md-2 col-form-label">Rekvisition</label>
<div class="col-md-4">
<label for="referenceNumber" class="col-sm-2 col-md-2 col-form-label">Rekvisition</label>
<div class="col-sm-10 col-md-4">
<InputText id="referenceNumber" class="form-control" @bind-Value="Activity.ReferenceNumber"/>
<ValidationMessage For="@(() => Activity.ReferenceNumber)"></ValidationMessage>
</div>
<label for="yourRef" class="col-md-2 col-form-label">Indkøber</label>
<div class="col-md-4">
<InputText id="yourRef" class="form-control" @bind-Value="Activity.YourRef"/>
<ValidationMessage For="@(() => Activity.YourRef)"></ValidationMessage>
</div>
</div>
<div class="row mb-1">
<label for="orderMessage" class="col-md-2 col-form-label">Note /Kontor</label>
<div class="col-md-4">
<label for="orderMessage" class="col-sm-2 col-md-2 col-form-label">Ordre notat</label>
<div class="col-sm-10 col-md-4">
<InputTextArea id="orderMessage" class="form-control" @bind-Value="Activity.OrderMessage"/>
<ValidationMessage For="@(() => Activity.OrderMessage)"></ValidationMessage>
</div>
</div>
<div class="row mb-2">
<label for="phone" class="col-md-2 col-form-label">Tlf.</label>
<div class="col-md-4">
<label for="phone" class="col-sm-2 col-md-2 col-form-label">Tlf.</label>
<div class="col-sm-10 col-md-4">
<InputText id="phone" class="form-control" @bind-Value="Activity.Phone"/>
<ValidationMessage For="@(() => Activity.Phone)"></ValidationMessage>
</div>
<div class="col-sm-2 col-md-2"></div>
<div class="col-sm-10 col-md-10">
<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 id="this-draft" style="@(Activity.ActivityStatusEnum is "order" or "quote" ? "display: block" : "display:none")">
@ -89,7 +78,7 @@ else
<table class="sticky-top table table-hover table-striped table-bordered">
<thead>
<tr class="bg-dark text-white">
<th scope="col" colspan="7">
<th scope="col" colspan="6">
Ordrekladde <span class="mx-2 draft-expires-msg">Global kladde (udløber efter @(DraftProvider.Draft.TimeToLiveInSeconds / 60)m inaktivitet)</span>
</th>
<th scope="col" class="text-end">
@ -163,14 +152,14 @@ else
</td>
<td class="align-middle">
<div class="input-group">
<input type="number" class="form-control" @bind-value="@Price"/>
<input type="number" class="form-control" @bind-value="@Price"/>
<button class="btn btn-warning" type="button" @onclick="CallPriceHistoryModal">
<i class="bi-list-ul"></i>
</button>
</div>
</td>
<td class="align-middle">
<input type="number" class="form-control" @bind-value="@Discount"/>
<input type="number" class="form-control" @bind-value="@Discount"/>
</td>
<td class="align-middle">@SelectedItem.Sku</td>
<td class="align-middle">
@ -229,10 +218,11 @@ else
</div>
</div>
</div>
</EditForm>
<div class="row mt-5 mb-2">
<div class="col-sm-10 text-end">
<button type="button" class="btn btn-warning" @onclick="CreateActivity" disabled="@(PoFormInvalid || Working)"><i class="bi-plus"></i> Opret ordre</button>
</div>
</EditForm>
<div class="row mt-5 mb-2">
<div class="col-sm-10 text-end">
<button type="button" class="btn btn-warning" @onclick="CreateActivity" disabled="@(PoFormInvalid || Working)"><i class="bi-plus"></i> Opret ordre</button>
</div>
}
</div>
<PriceListModal OnSelected="PriceListCallback" @ref="PriceList"/>

View file

@ -26,28 +26,32 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class CountryCreateNewOrderPage : IDisposable
public partial class OfficeCountryCreateOrderPage : IDisposable
{
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public string CountryCode { get; set; } = "";
[CascadingParameter] public DraftStateProvider DraftProvider { get; set; }
[Inject] public ILogger<CountryCreateNewOrderPage> Logger { get; set; }
[Inject] public ILogger<OfficeCountryCreateOrderPage> Logger { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public ICountryCustomerRepository CustomerRepo { get; set; }
[Inject] public ICountryCustomerHistoryRepository InventoryRepo { get; set; }
[Inject] public ICountryReportRepository ReportRepo { get; set; }
[Inject] public ISystemUserRepository UserRepo { get; set; }
[Inject] public ICountryCatalogRepository Catalog { get; set; }
// parameters
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public string CountryCode { get; set; } = "";
[CascadingParameter] public DraftStateProvider DraftProvider { get; set; }
private DateTime SelectedDate { get; set; }
private CompanyDto _company { get; set; } = new();
private List<ProductInventoryView> CustomerInventory { get; set; } = new();
// private variables
private readonly JsonSerializerOptions _options = new() {PropertyNameCaseInsensitive = true};
// class objects
private CompanyDto Customer { get; set; } = new();
private List<ProductInventoryView> CustomerInventory { get; set; } = new();
private SalesItemView SelectedItem { get; set; } = new();
private UserPref UserPrefs { get; set; } = new();
private ActivityDto Activity { get; set; } = new();
private WebUserInfoView SalesRep { get; set; } = new();
// edit context
private EditContext ActivityContext { get; set; }
// variables
private DateTime SelectedDate { get; set; }
private bool ShowItem { get; set; }
private string Quantity { get; set; } = "1";
private string Price { get; set; } = "0";
@ -55,67 +59,93 @@ public partial class CountryCreateNewOrderPage : IDisposable
private bool ReportClosed { get; set; }
private bool PoFormInvalid { get; set; } = true;
private bool Working { get; set; }
private WebUserInfoView ThisUserInfo { get; set; } = new();
private PriceListModal PriceList { get; set; } = new();
protected override async Task OnInitializedAsync()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
// setup edit context
ActivityContext = new EditContext(Activity);
ActivityContext.OnFieldChanged += HandleFieldChanged;
ActivityContext.OnValidationStateChanged += ValidationChanged;
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
_company = await CustomerRepo.GetByCustomerId(CountryCode, CompanyId);
// fetch customer
Customer = await CustomerRepo.GetByCustomerId(CountryCode, CompanyId);
Logger.LogDebug("Customer => {}", JsonSerializer.Serialize(Customer));
var today = $"{DateTime.Now:yyyy-MM-dd}";
var ts = _company.HistorySync;
if (ts != today)
ts = await InventoryRepo.InvoiceErpToCrmRpc(CountryCode, CompanyId, ts);
while (ts != today)
await Task.Delay(500);
// raise flag if report is closed
ReportClosed = await ReportRepo.ReportExist(_company.SalesRepId, ts);
// customer inventory
// initiate a sync to ensure up-to-date product history
if (Customer.HistorySync != today)
Customer.HistorySync = await InventoryRepo.InvoiceErpToCrmRpc(CountryCode, CompanyId, Customer.HistorySync);
// fetch customer inventory
CustomerInventory = await InventoryRepo.FetchInventory(CountryCode, CompanyId);
Logger.LogDebug("Inventory => {}", JsonSerializer.Serialize(CustomerInventory));
// get sales rep info
ThisUserInfo = await UserRepo.GetAdvisorInfo(_company.SalesRepId);
// setting up base data
Activity.BcId = _company.BcId;
SalesRep = await UserRepo.GetAdvisorInfo(Customer.SalesRepId);
Logger.LogDebug("SalesRep => {}", JsonSerializer.Serialize(SalesRep));
// set activity salesRep and countryCode
Activity.SalesRep = SalesRep.Advisor;
Activity.CountryCode = SalesRep.CountryCode;
// add customer info into activity properties
Activity.Account = Customer.Account;
Activity.VatNumber = Customer.VatNumber;
Activity.Email = Customer.Email;
Activity.Phone = Customer.Phone;
Activity.Mobile = Customer.Mobile;
Activity.Name = Customer.Name;
Activity.Address1 = Customer.Address1;
Activity.Address2 = Customer.Address2;
Activity.ZipCode = Customer.ZipCode;
Activity.City = Customer.City;
Activity.DlvName = Customer.Name;
Activity.DlvAddress1 = Customer.Address1;
Activity.DlvAddress2 = Customer.Address2;
Activity.DlvZipCode = Customer.ZipCode;
Activity.DlvCity = Customer.City;
Activity.BcId = Customer.BcId;
Activity.CompanyId = Customer.CompanyId;
Activity.SalesRepId = Customer.SalesRepId;
// setting up activity properties
Activity.ActivityStatusEnum = "noSale";
Activity.VisitTypeEnum = _company.Account is "" or "NY" ? "new" : "recall";
Activity.VisitTypeEnum = "recall";
Activity.ActivityTypeEnum = "phone";
Activity.ActivityStatusEnum = "order";
Activity.CompanyId = _company.CompanyId;
Activity.SalesRepId = _company.SalesRepId;
Activity.SalesRep = ThisUserInfo.Advisor;
Activity.CountryCode = ThisUserInfo.CountryCode;
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;
// Initialize date variable
SelectedDate = DateTime.Now;
}
private void CallPriceListModal()
{
PriceList.Show();
}
private async Task PriceListCallback(SelectedSku sku)
{
// get selected item
if (string.IsNullOrWhiteSpace(sku.ItemId))
return;
SelectedItem = await Catalog.GetSalesItemId(CountryCode, sku.ItemId);
ShowItem = true;
Price = sku.Rate;
Quantity = sku.Quantity;
StateHasChanged();
}
private void CallPriceHistoryModal()
{
}
private void DeleteDraft()
{
@ -141,7 +171,7 @@ public partial class CountryCreateNewOrderPage : IDisposable
/// <param name="workDate"></param>
private async Task WorkDateComponentCallback(string workDate)
{
ReportClosed = await ReportRepo.ReportExist(_company.SalesRepId, workDate);
ReportClosed = await ReportRepo.ReportExist(Customer.SalesRepId, workDate);
SelectedDate = DateTime.Parse(workDate);
Activity.ActivityDate = workDate;
}
@ -153,21 +183,6 @@ public partial class CountryCreateNewOrderPage : IDisposable
/// <param name="e"></param>
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
{
Logger.LogDebug("ActivityNewPage => HandleFieldChanged => ActivityStatusEnum <= '{}'", Activity.ActivityStatusEnum);
DraftProvider.Draft.DraftType = Activity.ActivityStatusEnum;
if (Activity.ActivityStatusEnum == "noSale")
{
Logger.LogDebug("ActivityNewPage => ActivityStatusEnum == 'noSale' <= remove items");
DraftProvider.Draft.Items = new List<DraftItem>();
}
// InvalidCanvas = InvalidActivityType;
if (Activity.YourRef.Length > 35 || Activity.ReferenceNumber.Length > 20 || DraftProvider.Draft.Items.Count == 0)
{
PoFormInvalid = true;
return;
}
PoFormInvalid = !ActivityContext.Validate();
StateHasChanged();
}
@ -179,11 +194,6 @@ public partial class CountryCreateNewOrderPage : IDisposable
/// <param name="e"></param>
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
{
if (string.IsNullOrEmpty(Activity.ActivityTypeEnum) && !ReportClosed)
{
PoFormInvalid = true;
return;
}
PoFormInvalid = false;
ActivityContext.OnFieldChanged -= HandleFieldChanged;
ActivityContext.OnValidationStateChanged -= ValidationChanged;

View file

@ -17,19 +17,21 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Warehouse")]
@attribute [Authorize(Roles = "Admin,Office,Warehouse")]
@page "/office/customers/{countryCode}"
<PageTitle>Kunde oversigt @CountryCode</PageTitle>
<div class="sticky-top bg-dark text-light rounded-2 px-3">
<div class="row g-3">
<div class="col-sm-2">
<CompanySearchColumnComponent OnChanged="SetSearchCol" />
<CustomerSearchColumnComponent OnChanged="SetSearchCol" />
</div>
<div class="col-sm-6">
<CompanySearchPhraseComponent OnChanged="SetSearchPhrase" />
<CustomerSearchPhraseComponent OnChanged="SetSearchPhrase" />
</div>
<div class="col-sm-2">
<CompanySortComponent OnChanged="SetSortCol" />
<CustomerSortComponent OnChanged="SetSortCol" />
</div>
<div class="col-sm-2">
<PageSizeComponent OnChanged="SetPageSize" />
@ -47,7 +49,7 @@
</div>
</div>
<CountryCustomerListComponent CompanyList="Companies" CountryCode="@CountryCode" />
<OfficeCountryCustomerListComponent CompanyList="Companies" CountryCode="@CountryCode" />
@if (Working)
{

View file

@ -28,7 +28,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages
{
public partial class CountryCustomerListPage : IDisposable
public partial class OfficeCountryCustomerListPage : IDisposable
{
[Parameter] public string CountryCode { get; set; } = "";
[Inject] public ILocalStorageService Storage { get; set; }

View file

@ -16,9 +16,9 @@
*@
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Warehouse")]
@attribute [Authorize(Roles = "Admin,Office,Warehouse")]
@page "/office/country"
<PageTitle>Kunde oversigt @CountryCode</PageTitle>
<div class="row">
<div class="col-lg-4 col-md-12 col-md-4 mb-4">
<div class="card">

View file

@ -4,7 +4,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class CountryLandingPage
public partial class OfficeCountryLandingPage
{
[Parameter] public string CountryCode { get; set; } = "";
}

View file

@ -17,10 +17,12 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Warehouse")]
@attribute [Authorize(Roles = "Admin,Office,Warehouse")]
@page "/print/catalog/{CountryCode}"
<CatalogPrintComponent ItemList="Items" CountryName="@UserInfo.CountryName" />
<PageTitle>Udskriv Katalog for @CountryName</PageTitle>
<CatalogPrintComponent ItemList="Items" CountryName="@CountryName" />
@if (Working)
{

View file

@ -21,6 +21,7 @@ using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository;
using Microsoft.AspNetCore.Components;
using Wonky.Client.Components;
using Wonky.Client.Helpers;
using Wonky.Client.HttpInterfaces;
using Wonky.Client.Services;
using Wonky.Entity.DTO;
@ -29,7 +30,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class CountryPrintCatalogPage : IDisposable
public partial class OfficeCountryPrintCatalogPage : IDisposable
{
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public ICountryCatalogRepository Catalog { get; set; }
@ -38,6 +39,7 @@ public partial class CountryPrintCatalogPage : IDisposable
private List<SalesItemView> Items { get; set; } = new();
private UserInfoView UserInfo { get; set; } = new();
private bool Working { get; set; } = true;
private string CountryName { get; set; } = "";
protected override async Task OnParametersSetAsync()
{
@ -46,7 +48,7 @@ public partial class CountryPrintCatalogPage : IDisposable
UserInfo = await Storage.GetItemAsync<UserInfoView>("_xu");
Items = await Catalog.GetPriceList(CountryCode);
CountryName = Utils.CountryName(CountryCode);
Working = false;
}

View file

@ -17,20 +17,22 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Warehouse")]
@attribute [Authorize(Roles = "Admin, Office")]
@page "/office/users/advisors/{CountryCode}/{UserId}/customers"
<PageTitle>Kundeliste for @SalesRep.FirstName @SalesRep.LastName</PageTitle>
<div class="sticky-top bg-dark text-light rounded-2 px-3">
<div class="container-fluid pt-3">
<div class="row mb-2">
<div class="col-md-3">
<CompanySearchColumnComponent OnChanged="SetSearchCol" />
<CustomerSearchColumnComponent OnChanged="SetSearchCol" />
</div>
<div class="col-md-3">
<CompanySearchPhraseComponent OnChanged="SetSearchPhrase" />
<CustomerSearchPhraseComponent OnChanged="SetSearchPhrase" />
</div>
<div class="col-md-3">
<CompanySortComponent OnChanged="SetSortCol" />
<CustomerSortComponent OnChanged="SetSortCol" />
</div>
<div class="col-md-3">
<PageSizeComponent OnChanged="SetPageSize" />
@ -47,13 +49,13 @@
<PaginationComponent MetaData="ResponseMeta" Spread="2" SelectedPage="SelectedPage"/>
</div>
<div class="col-3 justify-content-end">
<a class="btn btn-success text-nowrap" href="/customers/new">Opret kunde</a>
@* <a class="btn btn-success text-nowrap" href="/advisor/customers/new">Opret kunde</a> *@
</div>
</div>
</div>
</div>
<CountryCustomerListComponent CompanyList="CompanyList" />
<OfficeCountryCustomerListComponent CompanyList="@CompanyList" CountryCode="@CountryCode" />
@if (Working)
{

View file

@ -19,16 +19,18 @@ using Wonky.Client.HttpInterfaces;
using Wonky.Client.Services;
using Wonky.Entity.DTO;
using Wonky.Entity.Requests;
using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class CountrySalesRepCustomerListPage : IDisposable
public partial class OfficeCountrySalesRepCustomerListPage : IDisposable
{
[Parameter] public string UserId { get; set; } = "";
[Parameter] public string CountryCode { get; set; } = "dk";
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public ICountryCustomerRepository CustomerRepo { get; set; }
[Inject] public UserProfileService UserProfileService { get; set; }
[Inject] public ISystemUserRepository UserRepo { get; set; }
private List<CompanyDto> CompanyList { get; set; } = new();
private MetaData ResponseMeta { get; set; } = new();
private CustomerPaging Paging = new();
@ -36,12 +38,15 @@ public partial class CountrySalesRepCustomerListPage : IDisposable
private string SavedSearch { get; set; } = "";
private bool IncludeFolded { get; set; }
private bool Working { get; set; } = true;
private WebUserInfoView SalesRep { get; set; } = new();
protected override async Task OnParametersSetAsync()
{
Interceptor.DisposeEvent();
Interceptor.RegisterBeforeSendEvent();
SalesRep = await UserRepo.GetAdvisorInfo(UserId);
// set preferences
UserPref = await UserProfileService.GetPreferences();
Paging.OrderBy = UserPref.CompanySort;

View file

@ -0,0 +1,161 @@
@*
// 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 Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Admin,Office,Warehouse")]
@page "/office/customers/{CompanyId}/orders/{OrderId}"
<PageTitle>@_reportItem.ESalesNumber - @_reportItem.Company.Name</PageTitle>
<table class="table table-sm table-striped d-print-table">
<thead>
<tr>
<th class="p-0" colspan="4">
@if (_reportItem.Express)
{
<div id="watermark">
<i class="bi-lightning-charge text-dark" style="font-size: 11rem;"></i>
</div>
@if (_reportItem.ProcessStatusEnum == "None")
{
<AuthorizeView Roles="Admin,Office,Warehouse">
<Authorized>
<div class="d-print-none">
<div class="row">
<div class="col-sm-1">
<button type="button" class="btn btn-warning d-block" onclick="window.print();">PRINT</button>
</div>
<div class="col-sm-5">
<button type="button" class="btn btn-warning d-block" @onclick="SetExpressState" disabled="@_isNotified">Kvitter for modtagelse</button>
</div>
</div>
</div>
</Authorized>
</AuthorizeView>
}
}
<div class="bg-light text-dark border border-1 rounded-3 pt-3 mb-2">
<h2 class="fw-bold text-center">@_reportItem.Company.Name</h2>
@if (_reportItem.Express)
{
<h2 class="fw-bold text-center"><i class="bi-lightning-charge text-dark" style="font-size: 2rem;"></i> HASTER</h2>
}
@if (_reportItem.VisitTypeEnum.ToLower() == "phone" || _reportItem.OurRef.Contains("T:"))
{
<h5 class="text-center">TELEFONORDRE</h5>
}
@if (_reportItem.StatusTypeEnum is "Quote")
{
<h5 class="text-center">TILBUD</h5>
}
</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Dato</th>
<td>@_reportItem.OrderDate</td>
<th scope="row">Konto</th>
<td>@_reportItem.Company.Account</td>
</tr>
<tr>
<th scope="col">Telefon</th>
<td>@_reportItem.Company.Phone</td>
<th scope="col">Køber</th>
<td>@_reportItem.YourRef</td>
</tr>
<tr>
<th scope="col">CVR/VAT</th>
<td>@_reportItem.Company.VatNumber</td>
<th scope="col">Rekvisition</th>
<td>@_reportItem.ReferenceNumber</td>
</tr>
<tr>
<th scope="col">Navn</th>
<td>@_reportItem.Company.Name</td>
<th scope="col">Lev.Navn</th>
<td>@_reportItem.DlvName</td>
</tr>
<tr>
<th scope="col">Adresse</th>
<td>@_reportItem.Company.Address1</td>
<th scope="col">Lev.Adresse</th>
<td>@_reportItem.DlvAddress1</td>
</tr>
<tr>
<th scope="col">Adresse</th>
<td>@_reportItem.Company.Address2</td>
<th scope="col">Lev.Adresse</th>
<td>@_reportItem.DlvAddress2</td>
</tr>
<tr>
<th scope="col">Postnr By</th>
<td>@_reportItem.Company.ZipCode @_reportItem.Company.City</td>
<th scope="col">Lev.Postnr By</th>
<td>@_reportItem.DlvZipCity</td>
</tr>
</tbody>
</table>
<table class="table table-sm table-striped table-bordered">
<thead>
<tr class="bg-light text-black">
<th scope="col">Antal</th>
<th scope="col">Varnr</th>
<th scope="col">Beskrivelse</th>
<th class="text-end" scope="col">Pris</th>
<th class="text-end" scope="col">R%</th>
<th class="text-end" scope="col">Beløb</th>
</tr>
</thead>
<tbody>
@foreach (var line in _reportItem.Lines)
{
<tr>
<td>@line.Quantity</td>
<td>@line.Sku</td>
<td>@line.Description</td>
<td class="text-end">@($"{line.Price:N2}")</td>
<td class="text-end">@($"{line.Discount:N2}")</td>
<td class="text-end">@($"{line.LineSum:N2}")</td>
</tr>
}
<tr>
<td colspan="4"></td>
<td>Ordresum</td>
<td class="text-end">@_reportItem.OrderAmount</td>
</tr>
@if (_reportItem.Express)
{
<td class="bg-dark" colspan="4"></td>
<td class="text-end" colspan="2">
<h5 class="fw-bold"><i class="bi-lightning-charge the-fast" style="font-size: 2rem;"></i> HASTER</h5>
</td>
}
</tbody>
</table>
@if (!string.IsNullOrWhiteSpace(_reportItem.OfficeNote))
{
<div class="alert alert-dark">
<h4 class="text-center">@_reportItem.OfficeNote</h4>
</div>
}
@if (Working)
{
<WorkingThreeDots/>
}

View file

@ -0,0 +1,136 @@
// 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 System.Text;
using System.Text.Json;
using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpInterfaces;
using Wonky.Client.HttpRepository;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
using System.Security.Claims;
using Blazored.LocalStorage;
using Wonky.Client.Services;
namespace Wonky.Client.Pages;
public partial class OfficeCustomerOrderViewPage : IDisposable
{
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public string OrderId { get; set; } = "";
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IAdvisorActivityRepository AdvisorActivityRepo { get; set; }
[Inject] public ISystemSendMailService MailService { get; set; }
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public ISystemUserRepository SystemUserRepo { get; set; }
[Inject] public ILogger<OfficeCustomerOrderViewPage> Logger { get; set; }
[Inject] public IToastService Toast { get; set; }
private ReportItemView _reportItem { get; set; } = new();
private bool _isNotified { get; set; }
private bool Working { get; set; } = true;
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
protected override async Task OnInitializedAsync()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
// fetch order from backend
_reportItem = await AdvisorActivityRepo.GetReportItem(OrderId);
Logger.LogDebug("ReportItem => \n {}", JsonSerializer.Serialize(_reportItem, _options));
Working = false;
}
/// <summary>
/// Set activity process state to express. Send confirmation notification to salesRep
/// </summary>
private async Task SetExpressState()
{
// disable doubled actions
if (Working)
return;
Working = true;
Logger.LogDebug("GetExpressState => {}", JsonSerializer.Serialize(_reportItem, _options));
// send request to backend
var responseView = await AdvisorActivityRepo.GetExpressState(_reportItem.ActivityId);
Logger.LogDebug("SetExpressState => responseView <= {} ", JsonSerializer.Serialize(responseView));
// get user info from storage
var user = await Storage.GetItemAsync<UserInfoView>("_xu");
// fetch sales rep from response
var salesRep = await SystemUserRepo.GetAdvisorInfo(responseView.Id);
Logger.LogDebug("SetExpressState => salesRep => {}", JsonSerializer.Serialize(salesRep));
// create email notification body
var body = new StringBuilder();
body.AppendLine($"Kvittering for modtagelse af hasteordre {_reportItem.ESalesNumber}");
body.AppendLine($"Konto : {_reportItem.Company.Account}");
body.AppendLine($"Navn : {_reportItem.Company.Name}");
body.AppendLine(
$"Post By : {salesRep.CountryCode.ToUpper()}-{_reportItem.Company.ZipCode} {_reportItem.Company.City}");
body.AppendLine();
body.AppendLine("Med venlig hilsen");
body.AppendLine($"{user.FullName}");
body.AppendLine($"{user.PhoneNumber}");
// create a list of mail addresses
var sendTo = new List<EmailContact>
{
new()
{
Email = salesRep.Email,
Name = $"{salesRep.FirstName} {salesRep.LastName}"
}
};
// create an email
var msg = new EmailMessage
{
Body = body.ToString(),
Subject = $"Haste ordre til {_reportItem.Company.Name} er modtaget.",
To = sendTo,
IsBodyHtml = false
};
Logger.LogDebug("SetExpressState Notification => \n {}", JsonSerializer.Serialize(msg));
// send a system generated email
var sendMail = await MailService.SendMail("System", msg);
// result notification
if (sendMail.IsSuccess)
{
Toast
.ShowSuccess(
$"Status er opdateret og notifikation sendt til {salesRep.FirstName}.", "OK");
}
else
{
Toast
.ShowWarning(
$"Notifikation til {salesRep.FirstName} kunne ikke sendes. {sendMail.Message}", "ADVARSEL");
}
Logger.LogDebug("SendMail Result => \n {}", JsonSerializer.Serialize(sendMail));
// disable further notifications
_isNotified = true;
Working = false;
}
public void Dispose()
{
Interceptor.DisposeEvent();
}
}

View file

@ -0,0 +1,6 @@
#watermark {
position: fixed;
z-index: 999;
top: 10px;
right: 0;
}

View file

@ -17,14 +17,15 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin")]
@attribute [Authorize(Roles = "Admin, Office")]
@page "/office/users/advisors/{CountryCode}/{UserId}/reports"
<PageTitle>Rapport Arkiv @UserInfo.FirstName @UserInfo.LastName</PageTitle>
<div class="card">
<div class="card-header">
<h3>Rapport Arkiv - @UserInfo.FirstName @UserInfo.LastName</h3>
</div>
<ReportListOfficeComponent OnShowReport="ShowThisReport" CountryCode="@CountryCode" UserId="@UserId" ReportList="@ActivityReports" />
<OfficeReportListComponent OnShowReport="ShowThisReport" CountryCode="@CountryCode" UserId="@UserId" ReportList="@ActivityReports" />
</div>

View file

@ -23,7 +23,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class AdminReportListPage : IDisposable
public partial class OfficeReportListPage : IDisposable
{
[Parameter] public string UserId { get; set; } = "";
[Parameter] public string CountryCode { get; set; } = "";

View file

@ -18,7 +18,7 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Models
@attribute [Authorize(Roles = "Admin")]
@attribute [Authorize(Roles = "Admin, Office")]
@page "/office/users/advisors/{CountryCode}/{UserId}/reports/{ReportDate}"
<div class="row pt-2 pb-2 mb-3 rounded-2 d-print-none bg-dark text-white">
@ -53,7 +53,7 @@
<ReportDistanceLedgerComponent ReportData="Report.ReportData"/>
</div>
</div>
<ReportActivityTableOfficeComponent ActivityList="Report.ReportItems"/>
<OfficeReportActivityListComponent ActivityList="Report.ReportItems"/>
<ReportActivityLedgerComponent ReportData="Report.ReportData"/>
}
else

View file

@ -23,7 +23,7 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class AdminReportViewPage : IDisposable
public partial class OfficeReportViewPage : IDisposable
{
/// <summary>
/// Country code from url parameter
@ -65,7 +65,7 @@ public partial class AdminReportViewPage : IDisposable
/// Logger service
/// </summary>
[Inject]
public ILogger<AdminReportViewPage> Logger { get; set; }
public ILogger<OfficeReportViewPage> Logger { get; set; }
/// <summary>
/// Storage service

View file

@ -17,15 +17,17 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin")]
@attribute [Authorize(Roles = "Admin, Office")]
@page "/office/users/advisors/{CountryCode}"
<PageTitle>Sælger Oversigt @CountryName</PageTitle>
<div class="card">
<div class="card-header bg-dark text-white">
<h3>Sælgere</h3>
</div>
<div class="card-body">
<CountrySalesRepListComponent UserList="SalesReps" />
<OfficeCountrySalesRepListComponent UserList="SalesReps" />
</div>
</div>

View file

@ -1,22 +1,25 @@
using Microsoft.AspNetCore.Components;
using Wonky.Client.Helpers;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpInterfaces;
using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class AdminSalesRepListPage
public partial class OfficeSalesRepListPage :IDisposable
{
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public ISystemUserRepository SystemUserRepo { get; set; }
[Parameter] public string CountryCode { get; set; } = "";
private List<UserListAdminView> SalesReps { get; set; } = new();
private bool Working { get; set; } = true;
private string CountryName { get; set; } = "";
protected override async Task OnInitializedAsync()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
CountryName = Utils.CountryName(CountryCode);
var AdvisorList = await SystemUserRepo.GetAdvisors();
SalesReps = AdvisorList
.Where(x => x.CountryCode.ToLower() == CountryCode && Convert.ToInt32(x.SalesRep) < 100)

View file

@ -29,14 +29,14 @@
<div class="row mb-2">
<label class="col-md-3 col-form-label">Kunde søgning</label>
<div class="col-md-3">
<CompanySearchColumnComponent ></CompanySearchColumnComponent>
<CustomerSearchColumnComponent ></CustomerSearchColumnComponent>
</div>
</div>
<div class="row mb-2">
<label class="col-md-3 col-form-label">Kunde sortering</label>
<div class="col-md-3">
<CompanySortComponent ></CompanySortComponent>
<CustomerSortComponent ></CustomerSortComponent>
</div>
</div>

View file

@ -17,7 +17,7 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Advisor,Warehouse")]
@attribute [Authorize(Roles = "Admin,Office,Advisor,Warehouse")]
@page "/print/catalog"
<CatalogPrintComponent ItemList="Items" CountryName="@UserInfo.CountryName" />

View file

@ -34,14 +34,17 @@ public partial class PrintCatalogPage : IDisposable
[Inject] public ILocalStorageService Storage { get; set; }
[Inject] public IAdvisorCatalogRepository ItemRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
private List<SalesItemView> Items { get; set; } = new();
private UserInfoView UserInfo { get; set; } = new();
private bool Working { get; set; } = true;
protected override async Task OnInitializedAsync()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
UserInfo = await Storage.GetItemAsync<UserInfoView>("_xu");
Items = await ItemRepo.GetPriceList();

View file

@ -17,7 +17,7 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Advisor")]
@attribute [Authorize(Roles = "Admin,Office,Advisor")]
@page "/print/report/{CountryCode}/{UserId}/{ReportDate}"
<div class="row mb-3 d-print-none">
@ -44,6 +44,6 @@
<ReportDistanceLedgerComponent ReportData="Report.ReportData"/>
</div>
</div>
<ReportActivityTableOfficeComponent ActivityList="Report.ReportItems"/>
<OfficeReportActivityListComponent ActivityList="Report.ReportItems"/>
<ReportActivityLedgerComponent ReportData="Report.ReportData"/>
</div>

View file

@ -17,7 +17,7 @@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Advisor")]
@attribute [Authorize(Roles = "Admin,Office,Advisor")]
@page "/print/orders/{CountryCode}/{UserId}/{ReportDate}"
<div class="row mb-3 d-print-none">

Some files were not shown because too many files have changed in this diff Show more