Merge branch 'office-functionality---phone-order' into dev-v6
This commit is contained in:
commit
35cf79beba
207 changed files with 2608 additions and 1940 deletions
|
@ -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>
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
@code {
|
||||
|
||||
[Inject] public UserProfileService ProfileService { get; set; }
|
||||
[Inject] private UserProfileService ProfileService { get; set; }
|
||||
private int KmMorning { get; set; }
|
||||
private UserPref Prefs { get; set; } = new();
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
@if (ActivityList.Any())
|
||||
{
|
||||
<table class="table table-bordered d-print-table table-striped">
|
||||
<table class="table table-sm table-bordered d-print-table table-striped">
|
||||
<thead>
|
||||
<tr class="bg-dark text-white opacity-75 border-bottom">
|
||||
<th scope="col">Kunde</th>
|
||||
|
@ -38,7 +38,7 @@
|
|||
@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"><a 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>
|
|
@ -18,9 +18,9 @@ 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; }
|
||||
[Inject] private NavigationManager Navigator { get; set; }
|
||||
|
||||
}
|
|
@ -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>
|
|
@ -27,13 +27,13 @@ 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; }
|
||||
[Parameter] public EventCallback<string> OnSelect { get; set; }
|
||||
[Inject] public NavigationManager Navigator { get; set; }
|
||||
[Inject] public IJSRuntime Js { get; set; }
|
||||
[Inject] private NavigationManager Navigator { get; set; }
|
||||
[Inject] private IJSRuntime Js { get; set; }
|
||||
|
||||
private Lazy<IJSObjectReference> BsTooltip = new();
|
||||
|
||||
|
@ -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)
|
|
@ -0,0 +1,93 @@
|
|||
@using Wonky.Entity.Views
|
||||
@using Wonky.Entity.DTO
|
||||
@*
|
||||
// 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]
|
||||
//
|
||||
*@
|
||||
|
||||
<table class="table table-sm table-bordered table-striped">
|
||||
<thead>
|
||||
<tr class="bg-dark text-white opacity-75 border-bottom">
|
||||
<th></th>
|
||||
<th class="text-center" colspan="2" scope="col">Dagens Demo @(ReportData.NewDemoCount + ReportData.RecallDemoCount)</th>
|
||||
<th class="text-center border-end" colspan="2" scope="col">Dagens Resultat</th>
|
||||
<th class="text-center" colspan="4" scope="col">Måneds Resultat</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="bg-dark bg-opacity-50 border-bottom">
|
||||
<td></td>
|
||||
<th class="text-end text-white" scope="col">Besøg</th>
|
||||
<th class="text-end text-white" scope="col">Demo</th>
|
||||
<th class="text-end text-white" scope="col">Salg</th>
|
||||
<th class="text-end text-white border-end" scope="col">Beløb</th>
|
||||
<th class="text-end text-white" scope="col">Besøg</th>
|
||||
<th class="text-end text-white" scope="col">Demo</th>
|
||||
<th class="text-end text-white" scope="col">Salg</th>
|
||||
<th class="text-end text-white" scope="col">Beløb</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">N</th>
|
||||
<td class="text-end">@ReportData.NewVisitCount</td>
|
||||
<td class="text-end">@ReportData.NewDemoCount</td>
|
||||
<td class="text-end">@ReportData.NewSaleCount</td>
|
||||
<td class="text-end border-end">@ReportData.NewTurnover</td>
|
||||
<td class="text-end">@ReportData.NewVisitCountMonth</td>
|
||||
<td class="text-end">@ReportData.NewDemoCountMonth</td>
|
||||
<td class="text-end">@ReportData.NewSaleCountMonth</td>
|
||||
<td class="text-end">@ReportData.NewTurnoverMonth</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">R</th>
|
||||
<td class="text-end">@ReportData.RecallVisitCount</td>
|
||||
<td class="text-end">@ReportData.RecallDemoCount</td>
|
||||
<td class="text-end">@ReportData.RecallSaleCount</td>
|
||||
<td class="text-end border-end">@ReportData.RecallTurnover</td>
|
||||
<td class="text-end">@ReportData.RecallVisitCountMonth</td>
|
||||
<td class="text-end">@ReportData.RecallDemoCountMonth</td>
|
||||
<td class="text-end">@ReportData.RecallSaleCountMonth</td>
|
||||
<td class="text-end">@ReportData.RecallTurnoverMonth</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">SAS</th>
|
||||
<td class="bg-light"></td>
|
||||
<td class="bg-light"></td>
|
||||
<td class="text-end">@ReportData.SasCount</td>
|
||||
<td class="text-end border-end">@ReportData.SasTurnover</td>
|
||||
<td class="bg-light"></td>
|
||||
<td class="bg-light"></td>
|
||||
<td class="text-end">@ReportData.SasCountMonth</td>
|
||||
<td class="text-end">@ReportData.SasTurnoverMonth</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">TOTAL</th>
|
||||
<td class="text-end">@ReportData.TotalVisitCount</td>
|
||||
<td class="text-end">@ReportData.TotalDemoCount</td>
|
||||
<td class="text-end">@ReportData.TotalSaleCount</td>
|
||||
<td class="text-end border-end">@ReportData.TotalTurnover</td>
|
||||
<td class="text-end">@ReportData.TotalVisitCountMonth</td>
|
||||
<td class="text-end">@ReportData.TotalDemoCountMonth</td>
|
||||
<td class="text-end">@ReportData.TotalSaleCountMonth</td>
|
||||
<td class="text-end">@ReportData.TotalTurnoverMonth</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@code{
|
||||
|
||||
[Parameter]
|
||||
public ReportFiguresDto ReportData { get; set; } = new();
|
||||
|
||||
}
|
|
@ -22,8 +22,8 @@ namespace Wonky.Client.Components;
|
|||
|
||||
public partial class CatalogGroupComponent
|
||||
{
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] public UserProfileService ProfileService { get; set; }
|
||||
[Inject] private ILocalStorageService Storage { get; set; }
|
||||
[Inject] private UserProfileService ProfileService { get; set; }
|
||||
[Parameter] public EventCallback<string> OnChanged { get; set; }
|
||||
private Dictionary<string, string> Items { get; set; } = new();
|
||||
private UserPref Prefs = new();
|
||||
|
|
|
@ -24,5 +24,5 @@ namespace Wonky.Client.Components;
|
|||
public partial class CatalogListComponent
|
||||
{
|
||||
[Parameter] public List<SalesItemView> ItemList { get; set; } = new();
|
||||
[Inject] public IToastService ToastService { get; set; }
|
||||
[Inject] private IToastService ToastService { get; set; }
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
<select class="form-select bg-warning text-bg-warning" @bind-value="@SearchCol" @bind-value:event="oninput" @onchange="OnSelectChanged">
|
||||
<option value="-1" selected disabled>SØGNING</option>
|
||||
<option value="name">Søg Navn</option>
|
||||
<option value="sku">Søg Nummer</option>
|
||||
<option value="shortName">Søg Forkort.</option>
|
||||
<option value="name">Navn</option>
|
||||
<option value="sku">Nummer</option>
|
||||
<option value="shortName">Forkort.</option>
|
||||
</select>
|
|
@ -24,7 +24,7 @@ public partial class CatalogSearchComponent : IDisposable
|
|||
/// <summary>
|
||||
/// User preference service
|
||||
/// </summary>
|
||||
[Inject] public UserProfileService ProfileService { get; set; }
|
||||
[Inject] private UserProfileService ProfileService { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OnChanged event callback
|
||||
|
|
|
@ -17,6 +17,6 @@
|
|||
|
||||
<select class="form-select bg-success text-bg-success" @bind-value="@SortCol" @bind-value:event="oninput" @onchange="OnSelectChanged">
|
||||
<option value="-1" selected disabled>SORTERING</option>
|
||||
<option value="name">Navn sort</option>
|
||||
<option value="sku">Varenr sort</option>
|
||||
<option value="name">Navn</option>
|
||||
<option value="sku">Varenr</option>
|
||||
</select>
|
|
@ -24,7 +24,7 @@ public partial class CatalogSortComponent : IDisposable
|
|||
/// <summary>
|
||||
/// User preference service
|
||||
/// </summary>
|
||||
[Inject] public UserProfileService ProfileService { get; set; }
|
||||
[Inject] private UserProfileService ProfileService { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OnChanged callback function
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Wonky.Client.Components;
|
|||
|
||||
public partial class CustomerInventoryListComponent
|
||||
{
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] private ILocalStorageService Storage { get; set; }
|
||||
// Parameters
|
||||
[Parameter] public List<ProductInventoryView> Inventory { get; set; } = new();
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
{
|
||||
<div class="row">
|
||||
<div class="col-md-1"></div>
|
||||
<div class="col-md-1"><i class="bi-pencil"></i></div>
|
||||
<div class="col-md-1"><i class="bi-card-text"></i></div>
|
||||
<div class="col-md-10 fw-bold">@invoice.OrderNote</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ public partial class CustomerProductCheckListComponent
|
|||
{
|
||||
[Parameter] public List<ProductInventoryView> ProductList { get; set; } = new();
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] private ILocalStorageService Storage { get; set; }
|
||||
// private variables
|
||||
private bool Descending { get; set; }
|
||||
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
|
||||
<select class="form-select bg-warning text-bg-warning" @bind-value="@SearchCol" @bind-value:event="oninput" @onchange="OnSelectionChanged">
|
||||
<option value="-1" disabled>SØGNING</option>
|
||||
<option value="name">Søg Navn</option>
|
||||
<option value="city">Søg By</option>
|
||||
<option value="zip">Søg Post</option>
|
||||
<option value="account">Søg Konto</option>
|
||||
<option value="phone">Søg Tlf.</option>
|
||||
<option value="name">Navn</option>
|
||||
<option value="city">Bynavn</option>
|
||||
<option value="zip">Postnr</option>
|
||||
<option value="account">Konto</option>
|
||||
<option value="phone">Telefon</option>
|
||||
</select>
|
|
@ -22,10 +22,10 @@ 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; }
|
||||
[Inject] private ILocalStorageService Storage { get; set; }
|
||||
[Inject] private UserProfileService ProfileService { get; set; }
|
||||
[Parameter] public EventCallback<string> OnChanged { get; set; }
|
||||
private Dictionary<string, string> Items { get; set; } = new();
|
||||
private UserPref Prefs { get; set; } = new();
|
|
@ -20,12 +20,12 @@ 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; } = "";
|
||||
private UserPref Prefs { get; set; } = new ();
|
||||
[Inject] public UserProfileService ProfileService { get; set; }
|
||||
[Inject] private UserProfileService ProfileService { get; set; }
|
||||
[Parameter] public EventCallback<string> OnChanged { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
|
@ -17,6 +17,6 @@
|
|||
|
||||
<select class="form-select bg-success text-bg-success" @bind-value="@SortCol" @bind-value:event="oninput" @onchange="OnSelectionChanged">
|
||||
<option value="-1" selected disabled>SORTERING</option>
|
||||
<option value="name">Navne sort.</option>
|
||||
<option value="city">By sort.</option>
|
||||
<option value="name">Firma</option>
|
||||
<option value="city">Bynavn</option>
|
||||
</select>
|
|
@ -21,10 +21,10 @@ 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; }
|
||||
[Inject] private ILocalStorageService Storage { get; set; }
|
||||
[Inject] private UserProfileService ProfileService { get; set; }
|
||||
[Parameter] public EventCallback<string> OnChanged { get; set; }
|
||||
private Dictionary<string, string> Items { get; set; } = new();
|
||||
private UserPref Prefs = new();
|
75
Wonky.Client/Components/CustomerVisitListComponent.razor
Normal file
75
Wonky.Client/Components/CustomerVisitListComponent.razor
Normal file
|
@ -0,0 +1,75 @@
|
|||
@*
|
||||
// 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]
|
||||
//
|
||||
*@
|
||||
|
||||
<div class="list-group">
|
||||
<div class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h4>Dato</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Demo</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Salg</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Ordre Note</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Ordre Note</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (Activities.Any())
|
||||
{
|
||||
@foreach (var activity in Activities)
|
||||
{
|
||||
<div class="list-group-item list-group-item-action" style="cursor: pointer" @onclick="() => ShowVisitOverlay(activity.ActivityId)">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@activity.OrderDate
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.Demo
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.Sales
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.OfficeNote
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.CrmNote
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
Ingen data
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<CustomerActivityViewModalOverlay ReportItem="Activity" @ref="ActivityViewOverlay"/>
|
41
Wonky.Client/Components/CustomerVisitListComponent.razor.cs
Normal file
41
Wonky.Client/Components/CustomerVisitListComponent.razor.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
// 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.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using Blazored.LocalStorage;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Wonky.Client.HttpInterfaces;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Client.Shared;
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.Components;
|
||||
|
||||
public partial class CustomerVisitListComponent
|
||||
{
|
||||
[Parameter] public List<ReportItemView> Activities { get; set; } = new();
|
||||
private CustomerActivityViewModalOverlay ActivityViewOverlay { get; set; } = new();
|
||||
|
||||
private ReportItemView Activity { get; set; } = new();
|
||||
|
||||
private void ShowVisitOverlay(string activityId)
|
||||
{
|
||||
Activity = Activities.First(x => x.ActivityId == activityId);
|
||||
ActivityViewOverlay.Show();
|
||||
}
|
||||
|
||||
}
|
47
Wonky.Client/Components/InfoAdvisorComponent.razor
Normal file
47
Wonky.Client/Components/InfoAdvisorComponent.razor
Normal file
|
@ -0,0 +1,47 @@
|
|||
<h3>Sælger</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Symbol</th>
|
||||
<th>Betydning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<i class="bi-calendar" style="font-size:1.3rem"></i>
|
||||
</td>
|
||||
<td>ToDo liste</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<i class="bi-file-spreadsheet" style="font-size:1.3rem"></i>
|
||||
</td>
|
||||
<td>Pris katalog</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<i class="bi-building" style="font-size:1.3rem"></i>
|
||||
</td>
|
||||
<td>Firmaer/Kunder</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<i class="bi-calculator" style="font-size:1.3rem"></i>
|
||||
</td>
|
||||
<td>Aftaler/Tilbud</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<i class="bi-activity" style="font-size:1.3rem"></i>
|
||||
</td>
|
||||
<td>Aktivitet</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<i class="bi-file-earmark-spreadsheet" style="font-size:1.3rem"></i>
|
||||
</td>
|
||||
<td>Dagsrapporter</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
.pictogram {
|
||||
max-width: 30px;
|
||||
}
|
||||
.color-code {
|
||||
max-width: 40px;
|
||||
max-width: 30px;
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
.pictogram {
|
||||
max-width: 30px;
|
||||
}
|
||||
.color-code {
|
||||
max-width: 40px;
|
||||
max-width: 30px;
|
||||
}
|
41
Wonky.Client/Components/InfoCommonComponent.razor
Normal file
41
Wonky.Client/Components/InfoCommonComponent.razor
Normal file
|
@ -0,0 +1,41 @@
|
|||
<h3>Fælles</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Symbol</th>
|
||||
<th>Betydning</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="bi-cloud-arrow-up" style="font-size:1.3rem"></i></td>
|
||||
<td>Gem data</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="bi-search" style="font-size:1.3rem"></i></td>
|
||||
<td>Søg</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="bi-plus" style="font-size:1.3rem"></i></td>
|
||||
<td>Opret</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="bi-card-text" style="font-size:1.3rem"></i></td>
|
||||
<td>Notat</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="bi-printer" style="font-size:1.3rem"></i></td>
|
||||
<td>Udskrivning</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="bi-sliders" style="font-size:1.3rem"></i></td>
|
||||
<td>Indstillinger</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="bi-lock" style="font-size:1.3rem"></i></td>
|
||||
<td>Log af</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="bi-question" style="font-size:1.3rem"></i></td>
|
||||
<td>Hjælp/Info</td>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
17
Wonky.Client/Components/InfoOfficeComponent.razor
Normal file
17
Wonky.Client/Components/InfoOfficeComponent.razor
Normal file
|
@ -0,0 +1,17 @@
|
|||
<h3>Kontor</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Symbol</th>
|
||||
<th>Betydning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<i class="bi-people" style="font-size:1.3rem"></i>
|
||||
</td>
|
||||
<td>Brugere</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
<h3>Aktivitet Oversigt</h3>
|
||||
<h3>Bestilling Status</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -18,6 +18,10 @@
|
|||
<td><i class="bi-file-earmark" style="font-size:1.3rem"></i></td>
|
||||
<td>Ubehandlet</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="bi-hand-thumbs-up" style="font-size:1.3rem"></i></td>
|
||||
<td>Accepteret</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="bi-file-earmark-check" style="font-size:1.3rem"></i></td>
|
||||
<td>Plukket</td>
|
||||
|
@ -28,7 +32,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><i class="bi-truck" style="font-size:1.3rem"></i></td>
|
||||
<td>Afhentet</td>
|
||||
<td>Leveret</td>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
|
17
Wonky.Client/Components/InfoWarehouseComponent.razor
Normal file
17
Wonky.Client/Components/InfoWarehouseComponent.razor
Normal file
|
@ -0,0 +1,17 @@
|
|||
<h3>Lager</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Symbol</th>
|
||||
<th>Betydning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<i class="bi-box" style="font-size:1.3rem"></i>
|
||||
</td>
|
||||
<td>Pakning / Forsendelse</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
|
@ -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 />
|
||||
|
|
|
@ -32,7 +32,7 @@ using Wonky.Entity.Views;
|
|||
namespace Wonky.Client.Components;
|
||||
public partial class LandingComponentAdvisor
|
||||
{
|
||||
[Inject] public UserProfileService ProfileService { get; set; }
|
||||
[Inject] private UserProfileService ProfileService { get; set; }
|
||||
|
||||
private readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions
|
||||
{
|
||||
|
|
|
@ -24,15 +24,17 @@
|
|||
<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>
|
||||
</AuthorizeView>
|
||||
@*
|
||||
<a class="list-group-item list-group-item-action list-group-item-success" href="/office/customers/dk">
|
||||
<i class="bi-phone"></i> Tlf.Ordre
|
||||
<i class="bi-building"></i> Tlf.Ordre
|
||||
</a>
|
||||
<a class="list-group-item list-group-item-action list-group-item-info" href="/office/catalog/dk">
|
||||
*@
|
||||
<a class="list-group-item list-group-item-action list-group-item-info" href="/catalog/dk">
|
||||
<i class="bi-file-spreadsheet"></i> Priser
|
||||
</a>
|
||||
</div>
|
||||
|
@ -45,15 +47,17 @@
|
|||
<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>
|
||||
</AuthorizeView>
|
||||
@*
|
||||
<a class="list-group-item list-group-item-action list-group-item-success" href="/office/customers/no">
|
||||
<i class="bi-phone"></i> Tlf.Ordre
|
||||
</a>
|
||||
<a class="list-group-item list-group-item-action list-group-item-info" href="/office/catalog/no">
|
||||
*@
|
||||
<a class="list-group-item list-group-item-action list-group-item-info" href="/catalog/no">
|
||||
<i class="bi-file-spreadsheet"></i> Priser
|
||||
</a>
|
||||
</div>
|
||||
|
@ -66,15 +70,17 @@
|
|||
<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>
|
||||
</AuthorizeView>
|
||||
@*
|
||||
<a class="list-group-item list-group-item-action list-group-item-success" href="/office/customers/se">
|
||||
<i class="bi-phone"></i> Tlf.Ordre
|
||||
</a>
|
||||
<a class="list-group-item list-group-item-action list-group-item-info" href="/office/catalog/se">
|
||||
*@
|
||||
<a class="list-group-item list-group-item-action list-group-item-info" href="/catalog/se">
|
||||
<i class="bi-file-spreadsheet"></i> Priser
|
||||
</a>
|
||||
</div>
|
|
@ -30,9 +30,9 @@ 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; }
|
||||
[Inject] private UserProfileService ProfileService { get; set; }
|
||||
|
||||
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
|
||||
{
|
92
Wonky.Client/Components/OfficeActivityListComponent.razor
Normal file
92
Wonky.Client/Components/OfficeActivityListComponent.razor
Normal 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();
|
||||
|
||||
}
|
|
@ -32,7 +32,11 @@
|
|||
<a class="btn btn-success d-block" href="/office/users/advisors/@user.CountryCode.ToLower()/@user.UserId/customers">Kunder</a>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<a class="btn btn-info d-block" href="/office/users/advisors/@user.CountryCode.ToLower()/@user.UserId/view">Rediger</a>
|
||||
<AuthorizeView Roles="Admin">
|
||||
<Authorized>
|
||||
<a class="btn btn-info d-block" href="/office/users/advisors/@user.CountryCode.ToLower()/@user.UserId/view">Rediger</a>
|
||||
</Authorized>
|
||||
</AuthorizeView>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -19,7 +19,7 @@ using Wonky.Entity.Views;
|
|||
|
||||
namespace Wonky.Client.Components;
|
||||
|
||||
public partial class CountrySalesRepListComponent
|
||||
public partial class OfficeCountryAdvisorListComponent
|
||||
{
|
||||
[Parameter] public List<UserListAdminView> UserList { get; set; } = new();
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
@if (CompanyList.Any())
|
||||
{
|
||||
@*
|
||||
<div class="list-group list-group-flush">
|
||||
<div class="list-group-item px-3 bg-black text-white opacity-75">
|
||||
<div class="row">
|
||||
|
@ -40,9 +41,40 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
*@
|
||||
<div class="row d-flex g-3">
|
||||
@foreach (var company in CompanyList)
|
||||
{
|
||||
<a class=" list-group-item list-group-item-action" href="/office/customers/@CountryCode/@company.CompanyId/view">
|
||||
<div class="col-sm-6">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
@company.Name
|
||||
</h5>
|
||||
<div class="row">
|
||||
<div class="col-sm-3 col-md-3 fw-bold">Konto</div>
|
||||
<div class="col-sm-3 col-dm-3">@company.Account</div>
|
||||
|
||||
<div class="col-sm-3 col-md-3 fw-bold">CVR / ORG</div>
|
||||
<div class="col-sm-3 col-md-3">@company.VatNumber</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3 col-md-3 fw-bold">Telefon</div>
|
||||
<div class="col-sm-3 col-md-3">@company.Phone</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3 col-md-3 fw-bold">Adresse</div>
|
||||
<div class="col-sm-9 col-md-9">@company.Address1 @(string.IsNullOrWhiteSpace(company.Address2) ? "" : ",") @company.Address2</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3 col-md-3 fw-bold">Post By</div>
|
||||
<div class="col-sm-9 col-md-9">@company.CountryCode.ToUpper()-@company.ZipCode @company.City</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@*
|
||||
<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
|
||||
|
@ -61,6 +93,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</a>
|
||||
*@
|
||||
}
|
||||
</div>
|
||||
}
|
|
@ -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; } = "";
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
|
@ -15,9 +16,10 @@
|
|||
//
|
||||
*@
|
||||
|
||||
@using Wonky.Client.Helpers
|
||||
@if (ActivityList.Any())
|
||||
{
|
||||
<table class="table table-bordered d-print-table table-striped">
|
||||
<table class="table table-sm table-bordered d-print-table table-striped">
|
||||
<thead>
|
||||
<tr class="bg-dark text-white opacity-75 border-bottom">
|
||||
<th scope="col">Kunde</th>
|
||||
|
@ -27,10 +29,10 @@
|
|||
<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="oi oi-phone"></i></th>
|
||||
<th class="text-center" scope="col"><i class="oi oi-flash"></i></th>
|
||||
<th class="text-center" scope="col"><i class="oi oi-calculator"></i></th>
|
||||
<th class="text-center" scope="col"><i class="bi bi-truck"></i></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>
|
||||
|
@ -59,7 +61,7 @@
|
|||
<td class="align-middle state">
|
||||
@if (activity.Lines.Any() && activity.StatusTypeEnum == "Order")
|
||||
{
|
||||
<ProcessStateComponent StateClass="@GetProcessStatus(activity.ProcessStatusEnum)"/>
|
||||
<ProcessStateComponent StateClass="@Utils.GetProcessStatus(activity.ProcessStatusEnum)"/>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
|
@ -13,12 +13,18 @@
|
|||
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||
//
|
||||
|
||||
using Wonky.Entity.Views;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.Components;
|
||||
|
||||
public partial class ReportActivityLedgerComponent
|
||||
public partial class OfficeReportActivityListComponent
|
||||
{
|
||||
[Parameter] public ReportData ReportData { get; set; } = new();
|
||||
[Parameter] public List<ReportItemView> ActivityList { get; set; } = new();
|
||||
[Inject] private NavigationManager Navigator { get; set; }
|
||||
|
||||
private void ShowOrder(string companyId, string orderId)
|
||||
{
|
||||
Navigator.NavigateTo($"/office/customers/{companyId}/orders/{orderId}");
|
||||
}
|
||||
}
|
|
@ -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; } = "";
|
|
@ -23,18 +23,20 @@ namespace Wonky.Client.Components
|
|||
{
|
||||
public partial class PageSizeComponent : IDisposable
|
||||
{
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] public UserProfileService ProfileService { get; set; }
|
||||
[Inject] private ILocalStorageService Storage { get; set; }
|
||||
[Inject] private UserProfileService ProfileService { get; set; }
|
||||
[Parameter] public EventCallback<string> OnChanged { get; set; }
|
||||
private Dictionary<string, string> Items { get; set; } = new();
|
||||
private UserPref Prefs = new();
|
||||
private string PageSize { get; set; } = "";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
ProfileService.OnChange += ProfileServiceOnOnChange;
|
||||
Prefs = await ProfileService.GetPreferences();
|
||||
PageSize = Prefs.PageSize;
|
||||
}
|
||||
|
||||
private async Task OnSelectChanged(ChangeEventArgs e)
|
||||
{
|
||||
var val = e.Value.ToString();
|
||||
|
@ -42,11 +44,13 @@ namespace Wonky.Client.Components
|
|||
await OnChanged.InvokeAsync(val);
|
||||
await ProfileService.SetPageSize(val);
|
||||
}
|
||||
|
||||
private void ProfileServiceOnOnChange(UserPref newUserPref)
|
||||
{
|
||||
Prefs = newUserPref;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ProfileService.OnChange -= ProfileServiceOnOnChange;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
"the-bad" => "file-earmark-check",
|
||||
"the-ugly" => "box2-fill",
|
||||
"the-dead" => "truck",
|
||||
"accepted" => "hand-thumbs-up",
|
||||
_ => "question-square"
|
||||
};
|
||||
}
|
||||
|
|
|
@ -64,20 +64,20 @@
|
|||
</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))
|
||||
{
|
||||
<div class="col-sm-2 text-end">Note</div>
|
||||
<div class="col-sm-2 text-end">Kontor <i class="bi-card-text"></i></div>
|
||||
<div class="col-sm-10">
|
||||
<i class="bi-pencil"></i> @quote.OfficeNote
|
||||
@quote.OfficeNote
|
||||
</div>
|
||||
}
|
||||
@if (!string.IsNullOrWhiteSpace(quote.CrmNote))
|
||||
{
|
||||
<div class="col-sm-2 text-end">CRM note</div>
|
||||
<div class="col-sm-2 text-end">CRM <i class="bi-card-text"></i></div>
|
||||
<div class="col-sm-10">
|
||||
<i class="bi-pencil"></i> @quote.CrmNote
|
||||
@quote.CrmNote
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -8,11 +8,11 @@ public partial class QuoteListComponent
|
|||
{
|
||||
[Parameter]
|
||||
public List<ReportItemView> Quotes { get; set; } = new();
|
||||
[Parameter] public EventCallback<QuoteCallbackArgs> OnChangedCallback { get; set; }
|
||||
[Parameter] public EventCallback<QCallbackArgs> OnChangedCallback { get; set; }
|
||||
|
||||
private async Task SetQuote(string eSalesNumber, QStatus status)
|
||||
{
|
||||
var args = new QuoteCallbackArgs()
|
||||
var args = new QCallbackArgs()
|
||||
{
|
||||
ESalesNumber = eSalesNumber,
|
||||
Status = status
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@using Wonky.Entity.Views
|
||||
@*
|
||||
// Copyright (C) 2022 FCS Frede's Computer Services.
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
|
@ -84,4 +85,8 @@
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code{
|
||||
[Parameter] public ReportData ReportData { get; set; } = new();
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
// 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.Components;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.Components;
|
||||
|
||||
public partial class ReportActivityTableOfficeComponent
|
||||
{
|
||||
[Parameter] public List<ReportItemView> ActivityList { get; set; } = new();
|
||||
[Inject] public NavigationManager Navigator { get; set; }
|
||||
|
||||
private static string GetProcessStatus(string processStatus)
|
||||
{
|
||||
return processStatus.ToLower() switch
|
||||
{
|
||||
"express" => "the-fast",
|
||||
"none" => "the-good",
|
||||
"picked" => "the-bad",
|
||||
"packed" => "the-ugly",
|
||||
"shipped" => "the-dead",
|
||||
_ => "the-draw"
|
||||
};
|
||||
}
|
||||
|
||||
private void ShowOrder(string companyId, string orderId)
|
||||
{
|
||||
Navigator.NavigateTo($"office/customers/{companyId}/orders/{orderId}");
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th class="p-0" colspan="4">
|
||||
<div class="bg-light text-dark border border-1 rounded-3 pt-3 mb-2">
|
||||
<div class="alert d-print-block border border-1 border-dark pt-3 mb-2">
|
||||
<h2 class="fw-bold text-center">@ReportItem.Company.Name</h2>
|
||||
@if (ReportItem.Express)
|
||||
{
|
||||
|
@ -134,10 +134,10 @@
|
|||
</table>
|
||||
@if (!string.IsNullOrWhiteSpace(@ReportItem.OfficeNote))
|
||||
{
|
||||
<div class="alert alert-dark d-print-block">
|
||||
<h4 class="text-center">
|
||||
<div class="alert d-print-block border border-1 border-dark">
|
||||
<p class="text-center h4">
|
||||
@ReportItem.OfficeNote
|
||||
</h4>
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
|
@ -81,7 +81,7 @@
|
|||
}
|
||||
</tbody>
|
||||
</table>
|
||||
<ConfirmationModal BodyMessage="Handlingen kan ikke gøres om. Vil du slette opgaven?" OnOkClicked="DeleteTask" @ref="_confirmationModal"/>
|
||||
<ConfirmationModal BodyMessage="Handlingen kan ikke gøres om. Vil du slette opgaven?" OnOkClicked="DeleteTask" OnCancelClicked="OnCancelCallback" @ref="_confirmationModal"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -61,6 +61,10 @@ namespace Wonky.Client.Components
|
|||
_confirmationModal.Show();
|
||||
}
|
||||
|
||||
private void OnCancelCallback()
|
||||
{
|
||||
_confirmationModal.Hide();
|
||||
}
|
||||
/// <summary>
|
||||
/// Delete task call back
|
||||
/// </summary>
|
||||
|
|
|
@ -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>
|
|
@ -21,8 +21,8 @@
|
|||
<EditForm EditContext="WorkDateContext">
|
||||
<div class="container-fluid">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-sm-7 work-date">
|
||||
@SelectedDate.ToLongDateString()
|
||||
<div class="col-sm-7 fw-bold">
|
||||
d. @(SelectedDate.Day)/@(SelectedDate.Month)
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<InputDate class="form-control calendar" @bind-Value="SelectedDate" @oninput="OnDateChanged"/>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
@ -128,7 +146,8 @@ public static class Utils
|
|||
"picked" => "the-bad",
|
||||
"packed" => "the-ugly",
|
||||
"shipped" => "the-dead",
|
||||
_ => "question-square"
|
||||
"accepted" => "accepted",
|
||||
_ => "question"
|
||||
};
|
||||
}
|
||||
}
|
|
@ -14,6 +14,9 @@
|
|||
//
|
||||
|
||||
using System.Globalization;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Wonky.Client.Helpers;
|
||||
|
||||
|
@ -29,11 +32,11 @@ public class VatUtils
|
|||
/// <returns></returns>
|
||||
public static bool ValidateFormat(string countryCode, string vatNumber)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(vatNumber) || string.IsNullOrWhiteSpace(countryCode) || !IsDigitsOnly(vatNumber))
|
||||
if (string.IsNullOrWhiteSpace(vatNumber) || string.IsNullOrWhiteSpace(countryCode))
|
||||
return false;
|
||||
|
||||
|
||||
var sanitisedVat = SanitizeVatNumber(vatNumber);
|
||||
|
||||
|
||||
return countryCode.ToUpperInvariant() switch
|
||||
{
|
||||
"DK" => ValidateFormatDk(sanitisedVat),
|
||||
|
@ -43,6 +46,19 @@ public class VatUtils
|
|||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sanitize Vat remove everything but digits
|
||||
/// </summary>
|
||||
/// <param name="vatNumber"></param>
|
||||
/// <returns></returns>
|
||||
public static string SanitizeVatNumber(string vatNumber)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(vatNumber))
|
||||
return "";
|
||||
var regexObj = new Regex(@"[^\d]");
|
||||
return regexObj.Replace(vatNumber, "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate string is only numbers
|
||||
/// </summary>
|
||||
|
@ -96,6 +112,34 @@ public class VatUtils
|
|||
/// <param name="vatNumber"></param>
|
||||
/// <returns></returns>
|
||||
private static bool ValidateFormatSe(string vatNumber)
|
||||
{
|
||||
var vatToCheck = vatNumber;
|
||||
if (long.Parse(vatToCheck) == 0)
|
||||
return false;
|
||||
|
||||
switch (vatToCheck.Length)
|
||||
{
|
||||
// if less than 10 chars validate as SSI
|
||||
case 6:
|
||||
return ValidateFormatSeExt(vatToCheck);
|
||||
case < 10:
|
||||
return false;
|
||||
case > 10:
|
||||
vatNumber = vatNumber[..10];
|
||||
break;
|
||||
}
|
||||
// calculate check digit
|
||||
var c10 = C10(vatToCheck);
|
||||
// return comparison
|
||||
return $"{vatToCheck[..9]}{c10}" == vatNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate check digit for swedish org number
|
||||
/// </summary>
|
||||
/// <param name="orgNumber"></param>
|
||||
/// <returns></returns>
|
||||
private static int C10(string orgNumber)
|
||||
{
|
||||
// https://wiki.scn.sap.com/wiki/display/CRM/Sweden
|
||||
// 12 digits 0 to 9
|
||||
|
@ -104,23 +148,57 @@ public class VatUtils
|
|||
// Si = int(Ci/5) + (Ci*2)MOD10)
|
||||
// https://www.skatteverket.se/skatter/mervardesskattmoms/momsregistreringsnummer.4.18e1b10334ebe8bc80002649.html
|
||||
// C11 C12 == 01 (De två sista siffrorna är alltid 01)
|
||||
var vatToCheck = vatNumber;
|
||||
if (vatToCheck.Length < 10 || long.Parse(vatToCheck) == 0)
|
||||
return false;
|
||||
|
||||
|
||||
var r = new[] { 0, 2, 4, 6, 8 }
|
||||
.Sum(m => (int)char.GetNumericValue(vatToCheck[m]) / 5 +
|
||||
(int)char.GetNumericValue(vatToCheck[m]) * 2 % 10);
|
||||
var c1 = new[] { 1, 3, 5, 7 }.Sum(m => (int)char.GetNumericValue(vatToCheck[m]));
|
||||
var c10 = (10 - (r + c1) % 10) % 10;
|
||||
if (vatToCheck.Length == 10)
|
||||
{
|
||||
return $"{vatToCheck[..9]}{c10}" == vatNumber;
|
||||
}
|
||||
.Sum(m => (int)char.GetNumericValue(orgNumber[m]) / 5 +
|
||||
(int)char.GetNumericValue(orgNumber[m]) * 2 % 10);
|
||||
var c1 = new[] { 1, 3, 5, 7 }.Sum(m => (int)char.GetNumericValue(orgNumber[m]));
|
||||
var c10 = (10 - (r + c1) % 10) % 10;
|
||||
return c10;
|
||||
// end check digit calculation
|
||||
|
||||
return $"{vatToCheck[..9]}{c10}01" == vatNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
private static bool ValidateFormatSeExt(string data)
|
||||
{
|
||||
// Swedish personally held companies uses SSN number
|
||||
// a relaxed validation is required as only first 6 digits is supplied
|
||||
// birthday format e.g. 991231 yyMMdd
|
||||
|
||||
var y = int.Parse(data[..2]);
|
||||
var m = int.Parse(data[2..4]);
|
||||
var d = int.Parse(data[4..6]);
|
||||
// this calculation is only valid within 21st century
|
||||
var leap = y % 4 == 0; // 2000 was a leap year;
|
||||
// day
|
||||
if(d is < 1 or > 31)
|
||||
return false;
|
||||
// month
|
||||
switch (m)
|
||||
{
|
||||
// feb
|
||||
case 2:
|
||||
{
|
||||
if (leap)
|
||||
return d <= 29;
|
||||
return d <= 28;
|
||||
}
|
||||
// apr, jun, sep, nov
|
||||
case 4 or 6 or 9 or 11:
|
||||
return d <= 30;
|
||||
// jan, mar, may, july, aug, oct, dec
|
||||
case 1 or 3 or 5 or 7 or 8 or 10 or 12:
|
||||
return true;
|
||||
// does not exist
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulus11 validator
|
||||
/// </summary>
|
||||
|
@ -139,19 +217,4 @@ public class VatUtils
|
|||
|
||||
return sum % 11 == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sanitize Vat number to it's raw numbers
|
||||
/// </summary>
|
||||
/// <param name="vatNumber"></param>
|
||||
/// <returns></returns>
|
||||
private static string SanitizeVatNumber(string vatNumber)
|
||||
{
|
||||
return vatNumber.Replace(" ", "")
|
||||
.Replace("-", "")
|
||||
.Replace("DK", "")
|
||||
.Replace("NO", "")
|
||||
.Replace("SE", "")
|
||||
.Replace("MVA", "");
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Blazored.LocalStorage;
|
||||
using Blazored.Toast.Services;
|
||||
|
@ -31,7 +32,7 @@ namespace Wonky.Client.HttpInterceptors
|
|||
private readonly NavigationManager _navigation;
|
||||
private readonly IToastService _toast;
|
||||
private readonly RefreshTokenService _refreshTokenService;
|
||||
private ILogger<HttpInterceptorService> _logger;
|
||||
private readonly ILogger<HttpInterceptorService> _logger;
|
||||
private readonly ILocalStorageService _storage;
|
||||
private readonly IAuthenticationService _authenticationService;
|
||||
|
||||
|
@ -86,35 +87,37 @@ namespace Wonky.Client.HttpInterceptors
|
|||
if (e.Response == null || e.Response.IsSuccessStatusCode)
|
||||
return;
|
||||
|
||||
var message = "En fejl er opstået";
|
||||
var message = $"En fejl er opstået \n {JsonSerializer.Serialize(e)}";
|
||||
var currDoc = _navigation.ToBaseRelativePath(_navigation.Uri);
|
||||
if (currDoc.Contains("login/"))
|
||||
currDoc = "";
|
||||
|
||||
switch (e.Response.StatusCode)
|
||||
{
|
||||
case HttpStatusCode.NotFound:
|
||||
case HttpStatusCode.NotFound:
|
||||
_logger.LogDebug("NotFound <= {}", currDoc);
|
||||
break;
|
||||
case HttpStatusCode.BadRequest:
|
||||
_logger.LogDebug("BadRequest <= {}", currDoc);
|
||||
_logger.LogDebug("{}", message);
|
||||
break;
|
||||
case HttpStatusCode.Unauthorized:
|
||||
_logger.LogDebug("Unauthorized <= {}", currDoc);
|
||||
_logger.LogDebug("{}", message);
|
||||
_authenticationService.Logout();
|
||||
_navigation.NavigateTo($"/login/{currDoc}");
|
||||
message = "Venligst login ...";
|
||||
_toast.ShowInfo(message);
|
||||
_toast.ShowInfo("Venligst Login. Tak.");
|
||||
break;
|
||||
case HttpStatusCode.Conflict:
|
||||
_logger.LogDebug("Conflict <= {}", currDoc);
|
||||
_logger.LogDebug("{}", message);
|
||||
break;
|
||||
case HttpStatusCode.InternalServerError:
|
||||
// message = "Der er interne problemer på serveren ...";
|
||||
// _toast.ShowError(message);
|
||||
_logger.LogDebug("InternalServerError <= {}", currDoc);
|
||||
_logger.LogDebug("{}", message);
|
||||
break;
|
||||
default:
|
||||
_toast.ShowError(message);
|
||||
_logger.LogDebug("{}", message);
|
||||
break;
|
||||
}
|
||||
// throw new HttpResponseException(message);
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
// 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.Client.Features;
|
||||
using Wonky.Entity.Requests;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.HttpInterfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Interface Catalog Http repository
|
||||
/// </summary>
|
||||
public interface IAdvisorCatalogRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Get a paged sales item list
|
||||
/// </summary>
|
||||
/// <param name="pagingParameters"></param>
|
||||
/// <returns></returns>
|
||||
Task<PagingResponse<SalesItemView>> GetSalesItemsPaged(CatalogPaging pagingParameters);
|
||||
|
||||
/// <summary>
|
||||
/// Get sales item by id
|
||||
/// </summary>
|
||||
/// <param name="salesItemId"></param>
|
||||
/// <returns></returns>
|
||||
Task<SalesItemView> GetSalesItemId(string salesItemId);
|
||||
|
||||
/// <summary>
|
||||
/// Overload Get sales item by sku and country code
|
||||
/// </summary>
|
||||
/// <param name="sku"></param>
|
||||
/// <param name="countryCode"></param>
|
||||
/// <returns></returns>
|
||||
Task<SalesItemView> GetSalesItemSku(string countryCode, string sku);
|
||||
|
||||
/// <summary>
|
||||
/// Get sales item by variant id
|
||||
/// </summary>
|
||||
/// <param name="variantId"></param>
|
||||
/// <returns></returns>
|
||||
Task<SalesItemView> GetSalesVariantId(string variantId);
|
||||
|
||||
/// <summary>
|
||||
/// Complete catalog for print
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<List<SalesItemView>> GetPriceList();
|
||||
|
||||
/// <summary>
|
||||
/// Complete catalog for print country
|
||||
/// </summary>
|
||||
/// <param name="countryCode"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<SalesItemView>> GetPriceList(string countryCode);
|
||||
}
|
|
@ -66,5 +66,5 @@ public interface IAdvisorCustomerHistoryRepository
|
|||
/// <param name="companyId"></param>
|
||||
/// <param name="syncDate"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> ErpInvoiceToCrmRpc(string companyId, string syncDate);
|
||||
Task<string> InvoiceErpToCrmRpc(string companyId, string syncDate);
|
||||
}
|
|
@ -21,7 +21,7 @@ namespace Wonky.Client.HttpInterfaces;
|
|||
/// <summary>
|
||||
/// Interface for handling Customer Workplaces (chemical document service)
|
||||
/// </summary>
|
||||
public interface IWorkplaceRepository
|
||||
public interface IAdvisorWorkplaceRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Get Workplaces for given customer id
|
|
@ -28,9 +28,9 @@ public interface ICountryCatalogRepository
|
|||
/// Get a paged sales item list
|
||||
/// </summary>
|
||||
/// <param name="countryCode"></param>
|
||||
/// <param name="paging"></param>
|
||||
/// <param name="pager"></param>
|
||||
/// <returns></returns>
|
||||
Task<PagingResponse<SalesItemView>> GetSalesItemsPaged(string countryCode, CatalogPaging paging);
|
||||
Task<PagingResponse<SalesItemView>> GetSalesItemsPaged(string countryCode, CatalogPager pager);
|
||||
|
||||
/// <summary>
|
||||
/// Get sales item by id
|
|
@ -66,5 +66,5 @@ public interface ICountryCustomerHistoryRepository
|
|||
/// <param name="companyId"></param>
|
||||
/// <param name="syncDate"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> ErpInvoiceToCrmRpc(string countryCode, string companyId, string syncDate);
|
||||
Task<string> InvoiceErpToCrmRpc(string countryCode, string companyId, string syncDate);
|
||||
}
|
|
@ -13,6 +13,7 @@
|
|||
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||
//
|
||||
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.HttpInterfaces;
|
||||
|
@ -20,7 +21,7 @@ namespace Wonky.Client.HttpInterfaces;
|
|||
/// <summary>
|
||||
/// Interface for processing orders in warehouse
|
||||
/// </summary>
|
||||
public interface IWarehouseRepository
|
||||
public interface IOrderProcessRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Get warehouse order list by date
|
||||
|
@ -47,7 +48,7 @@ public interface IWarehouseRepository
|
|||
/// <summary>
|
||||
/// Update Order status setting new process status
|
||||
/// </summary>
|
||||
/// <param name="process"></param>
|
||||
/// <param name="processState"></param>
|
||||
/// <returns></returns>
|
||||
Task UpdateWarehouseOrderStatus(WarehouseProcess process);
|
||||
Task UpdateWarehouseOrderStatus(OrderProcessState processState);
|
||||
}
|
|
@ -36,7 +36,7 @@ public class AdvisorActivityRepository : IAdvisorActivityRepository
|
|||
};
|
||||
|
||||
private readonly NavigationManager _navigation;
|
||||
private ILogger<AdvisorActivityRepository> _logger;
|
||||
private readonly ILogger<AdvisorActivityRepository> _logger;
|
||||
private readonly HttpClient _client;
|
||||
private readonly ApiConfig _api;
|
||||
|
||||
|
@ -166,7 +166,7 @@ public class AdvisorActivityRepository : IAdvisorActivityRepository
|
|||
{
|
||||
Code = 404,
|
||||
IsSuccess = false,
|
||||
Message = "Uventet svare fra server",
|
||||
Message = "Uventet svar fra server",
|
||||
Id = ""
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,187 +0,0 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Wonky.Client.Features;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Wonky.Client.HttpInterfaces;
|
||||
using Wonky.Entity.Configuration;
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Requests;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.HttpRepository;
|
||||
|
||||
public class AdvisorCatalogRepository : IAdvisorCatalogRepository
|
||||
{
|
||||
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
private readonly NavigationManager _navigation;
|
||||
private ILogger<AdvisorCatalogRepository> _logger;
|
||||
private readonly HttpClient _client;
|
||||
private readonly ApiConfig _apiConfig;
|
||||
|
||||
public AdvisorCatalogRepository(HttpClient client,
|
||||
ILogger<AdvisorCatalogRepository> logger,
|
||||
NavigationManager navigation, IOptions<ApiConfig> configuration)
|
||||
{
|
||||
_client = client;
|
||||
_logger = logger;
|
||||
_navigation = navigation;
|
||||
_apiConfig = configuration.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a paged sales item list
|
||||
/// </summary>
|
||||
/// <param name="pagingParameters"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PagingResponse<SalesItemView>> GetSalesItemsPaged(CatalogPaging pagingParameters)
|
||||
{
|
||||
var queryString = new Dictionary<string, string>
|
||||
{
|
||||
["pageNumber"] = pagingParameters.PageNumber.ToString(),
|
||||
["pageSize"] = pagingParameters.PageSize.ToString(),
|
||||
["orderBy"] = pagingParameters.OrderBy,
|
||||
["searchColumn"] = pagingParameters.SearchColumn,
|
||||
["searchTerm"] = pagingParameters.SearchTerm,
|
||||
["selectGroup"] = pagingParameters.SelectGroup == "0" ? "" : pagingParameters.SelectGroup,
|
||||
};
|
||||
var response = await _client
|
||||
.GetAsync(QueryHelpers.AddQueryString($"{_apiConfig.Catalog}/page", queryString));
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return new PagingResponse<SalesItemView>
|
||||
{
|
||||
Items = new List<SalesItemView>(),
|
||||
MetaData = new MetaData()
|
||||
};
|
||||
}
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
var pagingResponse = new PagingResponse<SalesItemView>
|
||||
{
|
||||
Items = JsonSerializer.Deserialize<List<SalesItemView>>(content, _options),
|
||||
MetaData = JsonSerializer.Deserialize<MetaData>(
|
||||
response.Headers.GetValues("X-Pagination").First(), _options)
|
||||
};
|
||||
return pagingResponse;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a paged sales item list for country
|
||||
/// </summary>
|
||||
/// <param name="pagingParameters"></param>
|
||||
/// <param name="countryCode"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PagingResponse<SalesItemView>> GetSalesItemsPaged(CatalogPaging pagingParameters, string countryCode)
|
||||
{
|
||||
var queryString = new Dictionary<string, string>
|
||||
{
|
||||
["pageNumber"] = pagingParameters.PageNumber.ToString(),
|
||||
["pageSize"] = pagingParameters.PageSize.ToString(),
|
||||
["orderBy"] = pagingParameters.OrderBy,
|
||||
["searchColumn"] = pagingParameters.SearchColumn,
|
||||
["searchTerm"] = pagingParameters.SearchTerm,
|
||||
["selectGroup"] = pagingParameters.SelectGroup == "0" ? "" : pagingParameters.SelectGroup,
|
||||
};
|
||||
var response = await _client
|
||||
.GetAsync(QueryHelpers.AddQueryString($"{_apiConfig.Catalog}/page", queryString));
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return new PagingResponse<SalesItemView>
|
||||
{
|
||||
Items = new List<SalesItemView>(),
|
||||
MetaData = new MetaData()
|
||||
};
|
||||
}
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
var pagingResponse = new PagingResponse<SalesItemView>
|
||||
{
|
||||
Items = JsonSerializer.Deserialize<List<SalesItemView>>(content, _options),
|
||||
MetaData = JsonSerializer.Deserialize<MetaData>(
|
||||
response.Headers.GetValues("X-Pagination").First(), _options)
|
||||
};
|
||||
return pagingResponse;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get sales item by id
|
||||
/// </summary>
|
||||
/// <param name="salesItemId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<SalesItemView> GetSalesItemId(string salesItemId)
|
||||
{
|
||||
var salesItem = await _client
|
||||
.GetFromJsonAsync<SalesItemView>($"{_apiConfig.Catalog}/{salesItemId}");
|
||||
return salesItem ?? new SalesItemView();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overload Get sales item by sku and country code
|
||||
/// </summary>
|
||||
/// <param name="sku"></param>
|
||||
/// <param name="countryCode"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<SalesItemView> GetSalesItemSku(string countryCode, string sku)
|
||||
{
|
||||
var salesItem = await _client.GetFromJsonAsync<SalesItemView>($"{_apiConfig.Catalog}/sku/{countryCode}/{sku}");
|
||||
return salesItem ?? new SalesItemView();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get sales item by variant id
|
||||
/// </summary>
|
||||
/// <param name="variantId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<SalesItemView> GetSalesVariantId(string variantId)
|
||||
{
|
||||
var salesItem = await _client
|
||||
.GetFromJsonAsync<SalesItemView>($"{_apiConfig.Catalog}/variant/{variantId}");
|
||||
return salesItem ?? new SalesItemView();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Complete catalog for print
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<SalesItemView>> GetPriceList()
|
||||
{
|
||||
return await _client.GetFromJsonAsync<List<SalesItemView>>($"{_apiConfig.Catalog}", _options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Complete catalog for print country
|
||||
/// </summary>
|
||||
/// <param name="countryCode"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<SalesItemView>> GetPriceList(string countryCode)
|
||||
{
|
||||
return await _client.GetFromJsonAsync<List<SalesItemView>>($"{_apiConfig.Catalog}/{countryCode}", _options);
|
||||
}
|
||||
}
|
|
@ -128,9 +128,9 @@ public class AdvisorCustomerHistoryRepository : IAdvisorCustomerHistoryRepositor
|
|||
/// <param name="companyId"></param>
|
||||
/// <param name="syncDate"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> ErpInvoiceToCrmRpc(string companyId, string syncDate)
|
||||
public async Task<string> InvoiceErpToCrmRpc(string companyId, string syncDate)
|
||||
{
|
||||
var x = await _client.GetAsync($"{_api.CrmCustomers}/{companyId}/{_api.CrmRpcSyncExt}/{syncDate}");
|
||||
var x = await _client.GetAsync($"{_api.SyncRpc}/companies/{companyId}/{_api.SyncRpcInvoiceExt}/{syncDate}");
|
||||
if (!x.IsSuccessStatusCode)
|
||||
return string.Empty;
|
||||
var content = await x.Content.ReadAsStringAsync();
|
||||
|
|
|
@ -189,6 +189,8 @@ public class AdvisorCustomerRepository : IAdvisorCustomerRepository
|
|||
};
|
||||
var response = await _client.PutAsJsonAsync($"{_conf.CrmCustomers}/{companyId}/vat", model, _options);
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
return JsonSerializer.Deserialize<CompanyDto>(content);
|
||||
return response.IsSuccessStatusCode
|
||||
? JsonSerializer.Deserialize<CompanyDto>(content)
|
||||
: new CompanyDto{Name = "ERROR", VatNumber = vatNumber, CrmNotes = $"FEJL: {content}"};
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ public class AdvisorReportRepository : IAdvisorReportRepository
|
|||
private readonly NavigationManager _navigation;
|
||||
private ILogger<AdvisorReportRepository> _logger;
|
||||
private readonly HttpClient _client;
|
||||
private readonly ApiConfig _apiConfig;
|
||||
private readonly ApiConfig _api;
|
||||
|
||||
public AdvisorReportRepository(HttpClient client,
|
||||
ILogger<AdvisorReportRepository> logger,
|
||||
|
@ -44,7 +44,7 @@ public class AdvisorReportRepository : IAdvisorReportRepository
|
|||
_client = client;
|
||||
_logger = logger;
|
||||
_navigation = navigation;
|
||||
_apiConfig = configuration.Value;
|
||||
_api = configuration.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -55,7 +55,7 @@ public class AdvisorReportRepository : IAdvisorReportRepository
|
|||
public async Task<bool> ReportExist(string workDate)
|
||||
{
|
||||
var result = await _client.GetFromJsonAsync<SalesReportClosedView>(
|
||||
$"{_apiConfig.CrmReports}/exist/{workDate}");
|
||||
$"{_api.CrmReports}/exist/{workDate}");
|
||||
return result.ReportClosed;
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ public class AdvisorReportRepository : IAdvisorReportRepository
|
|||
/// <returns></returns>
|
||||
public async Task<List<SalesReportListView>> GetReports()
|
||||
{
|
||||
var result = await _client.GetAsync($"{_apiConfig.CrmReports}");
|
||||
var result = await _client.GetAsync($"{_api.CrmReports}");
|
||||
if (!result.IsSuccessStatusCode)
|
||||
return new List<SalesReportListView>();
|
||||
return await result.Content.ReadFromJsonAsync<List<SalesReportListView>>();
|
||||
|
@ -78,7 +78,7 @@ public class AdvisorReportRepository : IAdvisorReportRepository
|
|||
/// <returns></returns>
|
||||
public async Task<ReportView> GetReport(string workDate)
|
||||
{
|
||||
var result = await _client.GetFromJsonAsync<ReportView>($"{_apiConfig.CrmReports}/{workDate}");
|
||||
var result = await _client.GetFromJsonAsync<ReportView>($"{_api.CrmReports}/{workDate}");
|
||||
return result ?? new ReportView();
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ public class AdvisorReportRepository : IAdvisorReportRepository
|
|||
public async Task<ReportInitDto> InitializeReportData(string workDate)
|
||||
{
|
||||
var initData = await _client
|
||||
.GetFromJsonAsync<ReportInitDto>($"{_apiConfig.CrmReports}/init/{workDate}");
|
||||
.GetFromJsonAsync<ReportInitDto>($"{_api.CrmReports}/init/{workDate}");
|
||||
return initData ?? new ReportInitDto();
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ public class AdvisorReportRepository : IAdvisorReportRepository
|
|||
public async Task<ApiResponseView> CreateReport(string workDate, ReportDto reportDto)
|
||||
{
|
||||
var response = await _client
|
||||
.PostAsJsonAsync($"{_apiConfig.CrmReports}/{workDate}", reportDto, _options);
|
||||
.PostAsJsonAsync($"{_api.CrmReports}/{workDate}", reportDto, _options);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
return new ApiResponseView
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@ using Wonky.Entity.Views;
|
|||
|
||||
namespace Wonky.Client.HttpRepository;
|
||||
|
||||
public class WorkplaceRepository : IWorkplaceRepository
|
||||
public class AdvisorWorkplaceRepository : IAdvisorWorkplaceRepository
|
||||
{
|
||||
private readonly JsonSerializerOptions? _options = new JsonSerializerOptions
|
||||
{
|
||||
|
@ -32,12 +32,12 @@ public class WorkplaceRepository : IWorkplaceRepository
|
|||
};
|
||||
|
||||
private readonly NavigationManager _navigation;
|
||||
private ILogger<WorkplaceRepository> _logger;
|
||||
private ILogger<AdvisorWorkplaceRepository> _logger;
|
||||
private readonly HttpClient _client;
|
||||
private readonly ApiConfig _api;
|
||||
|
||||
public WorkplaceRepository(HttpClient client,
|
||||
ILogger<WorkplaceRepository> logger,
|
||||
public AdvisorWorkplaceRepository(HttpClient client,
|
||||
ILogger<AdvisorWorkplaceRepository> logger,
|
||||
NavigationManager navigation,
|
||||
IOptions<ApiConfig> configuration)
|
||||
{
|
|
@ -41,7 +41,7 @@ public class CountryCatalogRepository : ICountryCatalogRepository
|
|||
private readonly NavigationManager _navigation;
|
||||
private ILogger<CountryCatalogRepository> _logger;
|
||||
private readonly HttpClient _client;
|
||||
private readonly ApiConfig _apiConfig;
|
||||
private readonly ApiConfig _api;
|
||||
|
||||
public CountryCatalogRepository(HttpClient client,
|
||||
ILogger<CountryCatalogRepository> logger,
|
||||
|
@ -50,28 +50,28 @@ public class CountryCatalogRepository : ICountryCatalogRepository
|
|||
_client = client;
|
||||
_logger = logger;
|
||||
_navigation = navigation;
|
||||
_apiConfig = configuration.Value;
|
||||
_api = configuration.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a paged sales item list
|
||||
/// </summary>
|
||||
/// <param name="countryCode"></param>
|
||||
/// <param name="paging"></param>
|
||||
/// <param name="pager"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PagingResponse<SalesItemView>> GetSalesItemsPaged(string countryCode, CatalogPaging paging)
|
||||
public async Task<PagingResponse<SalesItemView>> GetSalesItemsPaged(string countryCode, CatalogPager pager)
|
||||
{
|
||||
var queryString = new Dictionary<string, string>
|
||||
{
|
||||
["pageNumber"] = paging.PageNumber.ToString(),
|
||||
["pageSize"] = paging.PageSize.ToString(),
|
||||
["orderBy"] = paging.OrderBy,
|
||||
["searchColumn"] = paging.SearchColumn,
|
||||
["searchTerm"] = paging.SearchTerm,
|
||||
["selectGroup"] = paging.SelectGroup == "0" ? "" : paging.SelectGroup
|
||||
["pageNumber"] = pager.PageNumber.ToString(),
|
||||
["pageSize"] = pager.PageSize.ToString(),
|
||||
["orderBy"] = pager.OrderBy,
|
||||
["searchColumn"] = pager.SearchColumn,
|
||||
["searchTerm"] = pager.SearchTerm,
|
||||
["selectGroup"] = pager.SelectGroup == "0" ? "" : pager.SelectGroup
|
||||
};
|
||||
var response = await _client
|
||||
.GetAsync(QueryHelpers.AddQueryString($"{_apiConfig.Catalog}/country/{countryCode}/page", queryString));
|
||||
.GetAsync(QueryHelpers.AddQueryString($"{_api.Catalog}/{countryCode}/page", queryString));
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
|
@ -102,7 +102,7 @@ public class CountryCatalogRepository : ICountryCatalogRepository
|
|||
public async Task<SalesItemView> GetSalesItemId(string countryCode, string salesItemId)
|
||||
{
|
||||
var salesItem = await _client
|
||||
.GetFromJsonAsync<SalesItemView>($"{_apiConfig.Catalog}/country/{countryCode}/{salesItemId}");
|
||||
.GetFromJsonAsync<SalesItemView>($"{_api.Catalog}/{countryCode}/{salesItemId}");
|
||||
return salesItem ?? new SalesItemView();
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ public class CountryCatalogRepository : ICountryCatalogRepository
|
|||
/// <returns></returns>
|
||||
public async Task<SalesItemView> GetSalesItemSku(string countryCode, string sku)
|
||||
{
|
||||
var salesItem = await _client.GetFromJsonAsync<SalesItemView>($"{_apiConfig.Catalog}/country/{countryCode}/sku/{sku}");
|
||||
var salesItem = await _client.GetFromJsonAsync<SalesItemView>($"{_api.Catalog}/{countryCode}/sku/{sku}");
|
||||
return salesItem ?? new SalesItemView();
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ public class CountryCatalogRepository : ICountryCatalogRepository
|
|||
public async Task<SalesItemView> GetSalesVariantId(string countryCode, string variantId)
|
||||
{
|
||||
var salesItem = await _client
|
||||
.GetFromJsonAsync<SalesItemView>($"{_apiConfig.Catalog}/country/{countryCode}/variant/{variantId}");
|
||||
.GetFromJsonAsync<SalesItemView>($"{_api.Catalog}/{countryCode}/variant/{variantId}");
|
||||
return salesItem ?? new SalesItemView();
|
||||
}
|
||||
|
||||
|
@ -138,6 +138,6 @@ public class CountryCatalogRepository : ICountryCatalogRepository
|
|||
/// <returns></returns>
|
||||
public async Task<List<SalesItemView>> GetPriceList(string countryCode)
|
||||
{
|
||||
return await _client.GetFromJsonAsync<List<SalesItemView>>($"{_apiConfig.Catalog}/country/{countryCode}", _options);
|
||||
return await _client.GetFromJsonAsync<List<SalesItemView>>($"{_api.Catalog}/{countryCode}", _options);
|
||||
}
|
||||
}
|
|
@ -134,9 +134,9 @@ public class CountryCustomerHistoryRepository : ICountryCustomerHistoryRepositor
|
|||
/// <param name="companyId"></param>
|
||||
/// <param name="syncDate"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> ErpInvoiceToCrmRpc(string countryCode, string companyId, string syncDate)
|
||||
public async Task<string> InvoiceErpToCrmRpc(string countryCode, string companyId, string syncDate)
|
||||
{
|
||||
var x = await _client.GetAsync($"{_api.OfficeCustomers}/{countryCode}/{companyId}/{_api.CrmRpcSyncExt}/{syncDate}");
|
||||
var x = await _client.GetAsync($"{_api.OfficeCustomers}/{countryCode}/{companyId}/{_api.SyncRpcInvoiceExt}/{syncDate}");
|
||||
if (!x.IsSuccessStatusCode)
|
||||
return string.Empty;
|
||||
var content = await x.Content.ReadAsStringAsync();
|
|
@ -145,5 +145,4 @@ public class CountryCustomerRepository : ICountryCustomerRepository
|
|||
Console.WriteLine(content);
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
|
||||
}
|
|
@ -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>
|
|
@ -19,11 +19,12 @@ using Microsoft.AspNetCore.Components;
|
|||
using Microsoft.Extensions.Options;
|
||||
using Wonky.Client.HttpInterfaces;
|
||||
using Wonky.Entity.Configuration;
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.HttpRepository;
|
||||
|
||||
public class WarehouseRepository : IWarehouseRepository
|
||||
public class OrderProcessRepository : IOrderProcessRepository
|
||||
{
|
||||
private readonly JsonSerializerOptions? _options = new JsonSerializerOptions
|
||||
{
|
||||
|
@ -31,12 +32,12 @@ public class WarehouseRepository : IWarehouseRepository
|
|||
};
|
||||
|
||||
private readonly NavigationManager _navigation;
|
||||
private ILogger<WarehouseRepository> _logger;
|
||||
private ILogger<OrderProcessRepository> _logger;
|
||||
private readonly HttpClient _client;
|
||||
private readonly ApiConfig _api;
|
||||
|
||||
public WarehouseRepository(HttpClient client,
|
||||
ILogger<WarehouseRepository> logger,
|
||||
public OrderProcessRepository(HttpClient client,
|
||||
ILogger<OrderProcessRepository> logger,
|
||||
NavigationManager navigation,
|
||||
IOptions<ApiConfig> configuration)
|
||||
{
|
||||
|
@ -81,11 +82,11 @@ public class WarehouseRepository : IWarehouseRepository
|
|||
/// <summary>
|
||||
/// Update Order status setting new process status
|
||||
/// </summary>
|
||||
/// <param name="process"></param>
|
||||
/// <param name="processState"></param>
|
||||
/// <returns></returns>
|
||||
public async Task UpdateWarehouseOrderStatus(WarehouseProcess process)
|
||||
public async Task UpdateWarehouseOrderStatus(OrderProcessState processState)
|
||||
{
|
||||
_logger.LogDebug("process => {}", JsonSerializer.Serialize(process, _options));
|
||||
await _client.PutAsJsonAsync($"{_api.Warehouse}/{process.OrderId}", process, _options);
|
||||
_logger.LogDebug("process => {}", JsonSerializer.Serialize(processState, _options));
|
||||
await _client.PutAsJsonAsync($"{_api.Warehouse}/{processState.OrderId}", processState, _options);
|
||||
}
|
||||
}
|
|
@ -7,5 +7,6 @@ public enum PStatus
|
|||
Packed,
|
||||
Shipped,
|
||||
All,
|
||||
Express
|
||||
Express,
|
||||
Accepted
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
namespace Wonky.Client.Models;
|
||||
|
||||
public class QuoteCallbackArgs
|
||||
public class QCallbackArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// ESalesNumber
|
|
@ -18,21 +18,23 @@
|
|||
@using Microsoft.AspNetCore.Authorization
|
||||
@using Wonky.Client.Components
|
||||
@attribute [Authorize(Roles = "Advisor")]
|
||||
@page "/customers/{CompanyId}/activities/new"
|
||||
@page "/advisor/customers/{CompanyId}/activities/new"
|
||||
|
||||
<PageTitle>Ny aktivitet - @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">
|
||||
<div class="row mb-2 bg-dark text-white rounded-3 p-3">
|
||||
<div class="col">
|
||||
<h3>@Activity.Name - @Activity.Account</h3>
|
||||
</div>
|
||||
|
@ -52,9 +54,9 @@ else
|
|||
<EditForm EditContext="ActivityContext">
|
||||
<DataAnnotationsValidator/>
|
||||
|
||||
<div class="row mb-1">
|
||||
<label for="activityType" class="col-md-2 col-form-label">Ordre Type</label>
|
||||
<div class="col-md-4">
|
||||
<div class="row mb-3 g-2">
|
||||
<label for="activityType" class="col-sm-2 col-form-label-sm">Ordre Type</label>
|
||||
<div class="col-sm-4">
|
||||
<InputSelect id="activityType" class="form-select bg-primary text-bg-primary" @bind-Value="@Activity.ActivityTypeEnum">
|
||||
<option value="">→ TAG MIG ←</option>
|
||||
<option value="onSite">Besøg</option>
|
||||
|
@ -63,11 +65,11 @@ else
|
|||
<ValidationMessage For="@(() => Activity.ActivityTypeEnum)"></ValidationMessage>
|
||||
</div>
|
||||
|
||||
<label for="statusType" class="col-md-2 col-form-label">Status</label>
|
||||
<div class="col-md-4">
|
||||
<label for="statusType" class="col-sm-2 col-form-label-sm">Status</label>
|
||||
<div class="col-sm-4">
|
||||
<InputSelect id="statusType" class="form-select bg-primary text-bg-primary" @bind-Value="@Activity.ActivityStatusEnum">
|
||||
<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")
|
||||
{
|
||||
|
@ -97,66 +99,78 @@ else
|
|||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-1">
|
||||
<label for="demo" class="col-md-2 col-form-label">Demo</label>
|
||||
<div class="col-md-4">
|
||||
<label for="demo" class="col-sm-2 col-form-label-sm">Demo</label>
|
||||
<div class="col-sm-4">
|
||||
<InputText id="demo" class="form-control" @bind-Value="Activity.Demo"/>
|
||||
<ValidationMessage For="@(() => Activity.Demo)"></ValidationMessage>
|
||||
</div>
|
||||
|
||||
<label for="email" class="col-md-2 col-form-label">Epost</label>
|
||||
<div class="col-md-4">
|
||||
<label for="email" class="col-sm-2 col-form-label-sm">Epost</label>
|
||||
<div class="col-sm-4">
|
||||
<InputText id="email" class="form-control" @bind-Value="Activity.Email"/>
|
||||
<ValidationMessage For="@(() => Activity.Email)"></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-form-label-sm">Rekvisition</label>
|
||||
<div class="col-sm-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">
|
||||
<label for="yourRef" class="col-sm-2 col-form-label-sm">Indkøber</label>
|
||||
<div class="col-sm-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">
|
||||
<InputTextArea id="orderMessage" class="form-control" @bind-Value="Activity.OrderMessage"/>
|
||||
<ValidationMessage For="@(() => Activity.OrderMessage)"></ValidationMessage>
|
||||
</div>
|
||||
|
||||
<label for="crmNote" class="col-md-2 col-form-label">Note /Selv</label>
|
||||
<div class="col-md-4">
|
||||
<InputTextArea id="crmNote" class="form-control" @bind-Value="Activity.CrmNote"/>
|
||||
<ValidationMessage For="@(() => Activity.CrmNote)"></ValidationMessage>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-2">
|
||||
<label for="attention" class="col-md-2 col-form-label">Att.</label>
|
||||
<div class="col-md-4">
|
||||
<label for="attention" class="col-sm-2 col-form-label-sm">Att.</label>
|
||||
<div class="col-sm-4">
|
||||
<InputText id="attention" class="form-control" @bind-Value="Activity.Attention"/>
|
||||
<ValidationMessage For="@(() => Activity.Attention)"></ValidationMessage>
|
||||
</div>
|
||||
|
||||
<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-form-label-sm">Tlf.</label>
|
||||
<div class="col-sm-4">
|
||||
<InputText id="phone" class="form-control" @bind-Value="Activity.Phone"/>
|
||||
<ValidationMessage For="@(() => Activity.Phone)"></ValidationMessage>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="orderMessage" class="col-sm-2 col-form-label-sm">Note /Kontor</label>
|
||||
<div class="col-sm-4">
|
||||
<InputTextArea id="orderMessage" class="form-control" @bind-Value="Activity.OrderMessage"/>
|
||||
<ValidationMessage For="@(() => Activity.OrderMessage)"></ValidationMessage>
|
||||
</div>
|
||||
|
||||
<label for="crmNote" class="col-sm-2 col-form-label-sm">Note /Selv</label>
|
||||
<div class="col-sm-4">
|
||||
<InputTextArea id="crmNote" class="form-control" @bind-Value="Activity.CrmNote"/>
|
||||
<ValidationMessage For="@(() => Activity.CrmNote)"></ValidationMessage>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6"></div>
|
||||
<label for="vatNumber" class="col-sm-2 col-form-label-sm">Cvr/Org nr.</label>
|
||||
<div class="col-sm-4">
|
||||
<InputText id="vatNumber" class="form-control" @bind-Value="Activity.VatNumber" />
|
||||
<ValidationMessage For="@(() => Activity.VatNumber)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-3">
|
||||
<div class="col-sm-3 d-grid mx-auto">
|
||||
<button class="btn btn-danger" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" @onclick="ShowInvoiceOverlay">Faktura</button>
|
||||
</div>
|
||||
<div class="col-sm-3 d-grid mx-auto">
|
||||
<button class="btn btn-warning" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" @onclick="ShowVisitOverlay">Tidl. besøg</button>
|
||||
@* <button class="btn btn-warning" disabled @onclick="ShowVisitOverlay">Tidl. besøg</button> *@
|
||||
</div>
|
||||
<div class="col-sm-3 d-grid mx-auto">
|
||||
<button class="btn btn-success" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" @onclick="ShowInventoryOverlay">Produkter</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="this-draft" style="@(Activity.ActivityStatusEnum is "order" or "quote" ? "display: block" : "display:none")">
|
||||
@* Order lines -----------------------------------------------------*@
|
||||
@* Draft lines in draft -----------------------------------------------------*@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<table class="sticky-top table table-hover table-striped table-bordered">
|
||||
|
@ -207,7 +221,7 @@ else
|
|||
<td class="align-middle text-black text-end fw-bold">@($"{DraftProvider.Draft.Total:N2}")</td>
|
||||
<td></td>
|
||||
<td class="align-middle text-end">
|
||||
<button class="btn btn-primary" type="button" @onclick="CallPriceListModal">
|
||||
<button class="btn btn-primary" type="button" @onclick="ShowPriceListOverlay">
|
||||
<i class="bi-plus"></i> Ny linje
|
||||
</button>
|
||||
</td>
|
||||
|
@ -216,7 +230,7 @@ else
|
|||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@* draft line ----------------------------------------------------- *@
|
||||
@* Create Draft line ----------------------------------------------------- *@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@if (!string.IsNullOrWhiteSpace(SelectedItem.Name) && ShowItem)
|
||||
|
@ -227,9 +241,9 @@ else
|
|||
<th scope="col" colspan="6">Kladdelinje</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="col">Antal</th>
|
||||
<th scope="col">Pris</th>
|
||||
<th scope="col">Rabat</th>
|
||||
<th style="min-width:100px;" scope="col">Antal</th>
|
||||
<th style="min-width:200px;" scope="col">Pris</th>
|
||||
<th style="min-width:100px;" scope="col">Rabat</th>
|
||||
<th class="align-content-center justify-content-center" scope="col">SAS</th>
|
||||
<th scope="col">Varenr.</th>
|
||||
<th scope="col"></th>
|
||||
|
@ -237,18 +251,18 @@ else
|
|||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="align-middle">
|
||||
<td class="align-middle" style="min-width:100px;">
|
||||
<input type="number" class="form-control" @bind-value="@Quantity"/>
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<td class="align-middle" style="min-width:200px;">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" @bind-value="@Price"/>
|
||||
<button class="btn btn-warning" type="button" @onclick="CallPriceHistoryModal">
|
||||
<button class="btn btn-warning" type="button" @onclick="ShowPriceHistoryOverlay">
|
||||
<i class="bi-list-ul"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<td class="align-middle" style="min-width:100px;">
|
||||
<input type="number" class="form-control" @bind-value="@Discount"/>
|
||||
</td>
|
||||
<td class="align-middle align-content-center justify-content-center">
|
||||
|
@ -256,7 +270,7 @@ else
|
|||
</td>
|
||||
<td class="align-middle">@SelectedItem.Sku</td>
|
||||
<td class="align-middle">
|
||||
<button type="button" class="btn btn-primary text-nowrap d-block" @onclick="@(() => AddItem(SelectedItem))">BESTIL @SelectedItem.Name</button>
|
||||
<button type="button" class="btn btn-primary d-block text-sm-center" @onclick="@(() => AddItem(SelectedItem))">@Quantity stk. @SelectedItem.Name</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -278,31 +292,31 @@ else
|
|||
aria-labelledby="deliveryHeader" data-bs-parent="#crmActivity">
|
||||
<div class="accordion-body">
|
||||
<div class="row mb-1">
|
||||
<label for="dlvName" class="col-md-2 col-form-label">Lev. Navn</label>
|
||||
<label for="dlvName" class="col-sm-2 col-form-label-sm">Lev. Navn</label>
|
||||
<div class="col-md-10">
|
||||
<InputText id="dlvName" class="form-control" @bind-Value="Activity.DlvName"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label for="dlvAddress1" class="col-md-2 col-form-label">Lev. Adresse</label>
|
||||
<label for="dlvAddress1" class="col-sm-2 col-form-label-sm">Lev. Adresse</label>
|
||||
<div class="col-md-10">
|
||||
<InputText id="dlvAddress1" class="form-control" @bind-Value="Activity.DlvAddress1"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label for="dlvAddress2" class="col-md-2 col-form-label">Lev. Adresse</label>
|
||||
<label for="dlvAddress2" class="col-sm-2 col-form-label-sm">Lev. Adresse</label>
|
||||
<div class="col-md-10">
|
||||
<InputText id="dlvAddress2" class="form-control" @bind-Value="Activity.DlvAddress2"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label for="dlvZipCode" class="col-md-2 col-form-label">Lev. Postnr</label>
|
||||
<label for="dlvZipCode" class="col-sm-2 col-form-label-sm">Lev. Postnr</label>
|
||||
<div class="col-md-10">
|
||||
<InputText id="dlvZipCode" class="form-control" @bind-Value="Activity.DlvZipCode"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label for="dlvCity" class="col-md-2 col-form-label">Lev. Bynavn</label>
|
||||
<label for="dlvCity" class="col-sm-2 col-form-label-sm">Lev. Bynavn</label>
|
||||
<div class="col-md-10">
|
||||
<InputText id="dlvCity" class="form-control" @bind-Value="Activity.DlvCity"/>
|
||||
</div>
|
||||
|
@ -314,16 +328,31 @@ 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>
|
||||
<button type="button" class="btn btn-warning" @onclick="CallConfirmCheckOverlay" disabled="@(PoFormInvalid || Working)"><i class="bi-cloud-arrow-up"></i> @ButtonText</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<ConfirmWorkDateModal BodyMessage="@PromptDateConfirm" OnOkClicked="WorkDateConfirmCallback" @ref="ConfirmWorkDateModal"/>
|
||||
<PriceListModal OnSelected="PriceListCallback" @ref="PriceListModal"/>
|
||||
<ProductHistoryModal CompanyId="@CompanyId" ItemSku="@SelectedItem.Sku" @ref="HistoryModal"/>
|
||||
<ProductPriceHistoryModal OnSelected="PriceHistoryCallback" CompanyId="@CompanyId" Sku="@SelectedItem.Sku" @ref="PriceHistoryModal"/>
|
||||
<ConfirmProductCheckModal BodyMessage="" CompanyId="@CompanyId" Products="CheckList" OnOkClicked="ConfirmProductCheckCallback" @ref="ConfirmProductCheckModal" />
|
||||
<ConfirmWorkDateModalOverlay BodyMessage="@PromptDateConfirm"
|
||||
OnOkClicked="WorkDateConfirmCallback" @ref="WorkDateOverlay"/>
|
||||
|
||||
<PriceCatalogModalOverlay CountryCode="@Company.CountryCode.ToLower()"
|
||||
OnSelected="PriceListCallback" @ref="CatalogOverlay"/>
|
||||
|
||||
<ProductHistoryModalOverlay CompanyId="@CompanyId" ItemSku="@SelectedItem.Sku" @ref="ProductOverlay"/>
|
||||
|
||||
<ProductPriceHistoryModal CompanyId="@CompanyId" Sku="@SelectedItem.Sku"
|
||||
OnSelected="PriceHistoryCallback" @ref="PriceOverlay"/>
|
||||
|
||||
<ConfirmProductCheckModalOverlay BodyMessage="" CompanyId="@CompanyId" Products="CheckList"
|
||||
OnOkClicked="ConfirmProductCheckCallback" @ref="ProductCheckOverlay" />
|
||||
|
||||
<CustomerInvoiceListModalOverlay CustomerInvoices="CompanyInvoices" @ref="InvoiceListOverlay" />
|
||||
|
||||
<CustomerInventoryListModalOverlay CompanyName="@Company.Name" CompanyId="@CompanyId" CountryCode="@Company.CountryCode"
|
||||
OnInventorySelected="OnInventoryCallback" Inventory="Inventory" @ref="InventoryListOverlay" />
|
||||
|
||||
<CustomerActivityListModalOverlay Activities="Activities" CompanyName="@Company.Name" @ref="ActivityListOverlay" />
|
|
@ -30,29 +30,30 @@ using Wonky.Entity.Views;
|
|||
|
||||
namespace Wonky.Client.Pages;
|
||||
|
||||
public partial class AdvisorCreateActivityPage : IDisposable
|
||||
public partial class AdvisorActivityCreatePage : IDisposable
|
||||
{
|
||||
// Parameters
|
||||
[CascadingParameter] DraftStateProvider DraftProvider { get; set; }
|
||||
[Parameter] public string CompanyId { get; set; }
|
||||
// Services
|
||||
[Inject] public ILogger<AdvisorCreateActivityPage> Logger { get; set; }
|
||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] public UserProfileService Profiles { get; set; }
|
||||
[Inject] public IToastService Toast { get; set; }
|
||||
[Inject] public NavigationManager Navigator { get; set; }
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] public IAdvisorCatalogRepository AdvisorCatalogCrm { get; set; }
|
||||
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||
[Inject] public IAdvisorActivityRepository AdvisorActivityRepo { get; set; }
|
||||
[Inject] public IAdvisorReportRepository AdvisorReportRepo { get; set; }
|
||||
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||
[Inject] private ILogger<AdvisorActivityCreatePage> Logger { get; set; }
|
||||
[Inject] private HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] private UserProfileService Profiles { get; set; }
|
||||
[Inject] private IToastService Toaster { get; set; }
|
||||
[Inject] private NavigationManager Navigator { get; set; }
|
||||
[Inject] private ILocalStorageService Storage { get; set; }
|
||||
[Inject] private ICountryCatalogRepository CatalogRepo { get; set; }
|
||||
[Inject] private IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||
[Inject] private IAdvisorActivityRepository ActivityRepo { get; set; }
|
||||
[Inject] private IAdvisorReportRepository ReportRepo { get; set; }
|
||||
[Inject] private IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||
|
||||
[CascadingParameter] private DraftStateProvider DraftProvider { get; set; } = new();
|
||||
[Parameter] public string CompanyId { get; set; }
|
||||
|
||||
// variables
|
||||
private readonly JsonSerializerOptions _options = new() {PropertyNameCaseInsensitive = true};
|
||||
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; }
|
||||
|
@ -64,21 +65,30 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
private bool InvalidActivity { get; set; } = true;
|
||||
private bool ReportClosed { get; set; }
|
||||
private bool Working { get; set; } = true;
|
||||
private UserInfoView ThisUserInfo { get; set; } = new();
|
||||
private UserInfoView SalesRep { get; set; } = new();
|
||||
private DateTime SelectedDate { get; set; }
|
||||
private string OldPhone { get; set; } = "";
|
||||
|
||||
private string PromptDateConfirm { get; set; } = "";
|
||||
// MODAL DIALOGS
|
||||
private PriceListModal PriceListModal { get; set; } = new();
|
||||
private ProductHistoryModal HistoryModal { get; set; } = new();
|
||||
private ProductPriceHistoryModal PriceHistoryModal { get; set; } = new();
|
||||
private ConfirmWorkDateModal ConfirmWorkDateModal { get; set; } = new();
|
||||
private ConfirmProductCheckModal ConfirmProductCheckModal { get; set; } = new();
|
||||
|
||||
// OVERLAY PAGES
|
||||
private PriceCatalogModalOverlay CatalogOverlay { get; set; } = new();
|
||||
private ProductHistoryModalOverlay ProductOverlay { get; set; } = new();
|
||||
private ProductPriceHistoryModal PriceOverlay { get; set; } = new();
|
||||
private ConfirmWorkDateModalOverlay WorkDateOverlay { get; set; } = new();
|
||||
private ConfirmProductCheckModalOverlay ProductCheckOverlay { get; set; } = new();
|
||||
private CustomerInvoiceListModalOverlay InvoiceListOverlay { get; set; } = new();
|
||||
private CustomerInventoryListModalOverlay InventoryListOverlay { get; set; } = new();
|
||||
private CustomerActivityListModalOverlay ActivityListOverlay { get; set; } = new();
|
||||
private List<ProductInventoryView> Inventory { get; set; } = new();
|
||||
private List<ProductInventoryView> CheckList { get; set; } = new();
|
||||
private InvoiceListView CompanyInvoices { get; set; } = new();
|
||||
|
||||
private List<ReportItemView> Activities { get; set; } = new();
|
||||
|
||||
|
||||
private string ButtonText { get; set; } = "Gem besøg";
|
||||
|
||||
|
||||
private bool OrgWarning { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Page initialization
|
||||
/// </summary>
|
||||
|
@ -93,54 +103,55 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
// User Preferences
|
||||
UserPrefs = await Profiles.GetPreferences();
|
||||
// User Info
|
||||
ThisUserInfo = await Storage.GetItemAsync<UserInfoView>("_xu");
|
||||
SalesRep = 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.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.VisitTypeEnum = Company.Account is "" or "NY" ? "new" : "recall";
|
||||
Activity.CompanyId = Company.CompanyId;
|
||||
Activity.SalesRepId = SalesRep.Id;
|
||||
Activity.SalesRep = SalesRep.Advisor;
|
||||
Activity.CountryCode = SalesRep.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 = string.IsNullOrWhiteSpace(UserPrefs.WorkDate) ? DateTime.Now : DateTime.Parse(UserPrefs.WorkDate);
|
||||
// raise flag if report is closed
|
||||
ReportClosed = await AdvisorReportRepo.ReportExist($"{SelectedDate:yyyy-MM-dd}");
|
||||
ReportClosed = await ReportRepo.ReportExist($"{SelectedDate:yyyy-MM-dd}");
|
||||
// Ask for confirmation of date
|
||||
Logger.LogDebug("Preferences.DateConfirmed => {}", UserPrefs.DateConfirmed);
|
||||
if (!UserPrefs.DateConfirmed)
|
||||
{
|
||||
PromptDateConfirm = $"Aktiviteter oprettes med dato {SelectedDate.ToShortDateString()}. Er dette OK?";
|
||||
ConfirmWorkDateModal.Show();
|
||||
WorkDateOverlay.Show();
|
||||
}
|
||||
// Lines may already have been added from the company inventory page
|
||||
if (DraftProvider.Draft.DraftType == "order")
|
||||
|
@ -151,14 +162,90 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
PoFormInvalid = false;
|
||||
}
|
||||
Working = false;
|
||||
//StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task CallConfirmProductCheckModel()
|
||||
private async Task ShowVisitOverlay()
|
||||
{
|
||||
Logger.LogDebug("ShowInventoryOverlay - wait for visits");
|
||||
|
||||
ActivityListOverlay.Show();
|
||||
|
||||
Activities = await ActivityRepo.GetCustomerActivities(CompanyId);
|
||||
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
private async Task ShowInventoryOverlay()
|
||||
{
|
||||
Logger.LogDebug("ShowInventoryOverlay - wait for inventory");
|
||||
|
||||
InventoryListOverlay.Show();
|
||||
|
||||
Inventory = await HistoryRepo.FetchInventory(CompanyId);
|
||||
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
private async Task OnInventoryCallback(DraftItem item)
|
||||
{
|
||||
Activity.ActivityStatusEnum = "order";
|
||||
DraftProvider.Draft.DraftType = "order";
|
||||
DraftProvider.Draft.Items.Add(item);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task ShowInvoiceOverlay()
|
||||
{
|
||||
Logger.LogDebug("ShowInvoiceOverlay - wait for invoices");
|
||||
|
||||
InvoiceListOverlay.Show();
|
||||
CompanyInvoices = await FetchCompanyInvoices();
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
private async Task<InvoiceListView> FetchCompanyInvoices()
|
||||
{
|
||||
// fetch from storage
|
||||
var storage = await Storage.GetItemAsStringAsync($"{CompanyId}-invoices");
|
||||
await Task.Delay(500);
|
||||
var iDate = await Storage.GetItemAsStringAsync($"{CompanyId}-iDate");
|
||||
|
||||
// if we have a list and iDate was today return the list
|
||||
if (!string.IsNullOrWhiteSpace(storage) && (!string.IsNullOrWhiteSpace(iDate) && DateTime.Parse(iDate.Replace("\"", "")) >= DateTime.Now))
|
||||
{
|
||||
Logger.LogDebug("fetching invoices from storage");
|
||||
Logger.LogDebug("storage contains <= {}", storage);
|
||||
return JsonSerializer.Deserialize<InvoiceListView>(storage);
|
||||
}
|
||||
|
||||
Logger.LogDebug("pulling invoices from backend");
|
||||
// pull invoices
|
||||
var companyInvoices = await HistoryRepo.FetchInvoiceList(CompanyId);
|
||||
// send invoices to storage
|
||||
await Storage.SetItemAsync($"{CompanyId}-invoices", companyInvoices);
|
||||
await Storage.SetItemAsync($"{CompanyId}-iDate", $"{DateTime.Now:yyyy-MM-dd}");
|
||||
Logger.LogDebug(" --> return invoices from backend");
|
||||
Working = false;
|
||||
Logger.LogDebug("backend contains <= {}", JsonSerializer.Serialize(companyInvoices));
|
||||
return companyInvoices;
|
||||
}
|
||||
|
||||
private void ShowOrgWarning()
|
||||
{
|
||||
if (OrgWarning)
|
||||
return;
|
||||
OrgWarning = true;
|
||||
if (Company.CountryCode.ToLower() == "se" && VatUtils.SanitizeVatNumber(Activity.VatNumber).Length < 10 && Activity.ActivityStatusEnum == "order")
|
||||
{
|
||||
Toaster.ShowWarning("Org nummer er ufuldstændig. Skal opdateres før bestilling kan sendes. ", "ADVARSEL");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CallConfirmCheckOverlay()
|
||||
{
|
||||
// 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
|
||||
|
@ -172,23 +259,26 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
Logger.LogDebug("pStorage => {}", pStorage);
|
||||
// fetch pDate from storage
|
||||
var pDate = await Storage.GetItemAsync<string>($"{CompanyId}-pDate");
|
||||
if (string.IsNullOrWhiteSpace(pDate))
|
||||
pDate = $"{DateTime.Now.AddDays(-1):yyyy-MM-dd}";
|
||||
Logger.LogDebug("pDate => {}", pDate);
|
||||
|
||||
// check if product data is valid and updated today
|
||||
if (string.IsNullOrWhiteSpace(pStorage) || pDate.Replace("\"", "") != $"{DateTime.Now:yyyy-MM-dd}")
|
||||
{
|
||||
Working = true;
|
||||
// pop a message
|
||||
Toast.ShowError("Produkt gennemgang mangler. Vent mens produkt oversigt indlæses. Gå ikke væk fra siden!", "Produkt check ...");
|
||||
Toaster.ShowError("Produkt gennemgang mangler. Vent mens produkt oversigt indlæses. Gå ikke væk fra siden!", "Produkt check ...");
|
||||
// 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.ErpInvoiceToCrmRpc(CompanyId, _company.HistorySync);
|
||||
Toaster.ShowInfo("Vent mens data synkroniseres ...", "ERP til CRM ...");
|
||||
var ts = await HistoryRepo.InvoiceErpToCrmRpc(CompanyId, Company.HistorySync);
|
||||
while (string.IsNullOrWhiteSpace(ts))
|
||||
await Task.Delay(500);
|
||||
// save pDate
|
||||
await Storage.SetItemAsync($"{CompanyId}-pDate", ts);
|
||||
// request products from backend
|
||||
Toast.ShowInfo("Vent mens produkt oversigt hentes", "CRM produkt liste");
|
||||
Toaster.ShowInfo("Vent mens produkt oversigt hentes", "CRM produkt liste");
|
||||
|
||||
CheckList = await HistoryRepo.FetchInventory(CompanyId);
|
||||
if(CheckList.Any())
|
||||
|
@ -206,11 +296,12 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
}
|
||||
|
||||
// Show CheckList modal
|
||||
ConfirmProductCheckModal.Show();
|
||||
ProductCheckOverlay.Show();
|
||||
}
|
||||
|
||||
private async Task ConfirmProductCheckCallback()
|
||||
{
|
||||
ConfirmProductCheckModal.Hide();
|
||||
ProductCheckOverlay.Hide();
|
||||
await CreateActivity();
|
||||
foreach (var item in CheckList)
|
||||
{
|
||||
|
@ -226,7 +317,7 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
private async Task WorkDateConfirmCallback()
|
||||
{
|
||||
await Profiles.SetDateConfirmed(true);
|
||||
ConfirmWorkDateModal.Hide();
|
||||
WorkDateOverlay.Hide();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
@ -236,7 +327,7 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
/// <param name="workDate"></param>
|
||||
private async Task WorkDateComponentCallback(string workDate)
|
||||
{
|
||||
ReportClosed = await AdvisorReportRepo.ReportExist(workDate);
|
||||
ReportClosed = await ReportRepo.ReportExist(workDate);
|
||||
SelectedDate = DateTime.Parse(workDate);
|
||||
Activity.ActivityDate = workDate;
|
||||
}
|
||||
|
@ -244,9 +335,9 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
/// <summary>
|
||||
/// Show Price list modal
|
||||
/// </summary>
|
||||
private void CallPriceListModal()
|
||||
private void ShowPriceListOverlay()
|
||||
{
|
||||
PriceListModal.Show();
|
||||
CatalogOverlay.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -258,7 +349,7 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
// get selected item
|
||||
if (string.IsNullOrWhiteSpace(sku.ItemId))
|
||||
return;
|
||||
SelectedItem = await AdvisorCatalogCrm.GetSalesItemId(sku.ItemId);
|
||||
SelectedItem = await CatalogRepo.GetSalesItemId(SalesRep.CountryCode.ToLower(), sku.ItemId);
|
||||
ShowItem = true;
|
||||
Price = sku.Rate;
|
||||
Quantity = sku.Quantity;
|
||||
|
@ -268,10 +359,10 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
/// <summary>
|
||||
/// Show Price History modal
|
||||
/// </summary>
|
||||
private void CallPriceHistoryModal()
|
||||
private void ShowPriceHistoryOverlay()
|
||||
{
|
||||
if(ShowItem)
|
||||
PriceHistoryModal.Show();
|
||||
PriceOverlay.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -294,26 +385,35 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
// avoid duplication
|
||||
if (Working)
|
||||
return;
|
||||
// validate customer address1 - this is a required input
|
||||
// validate customer address1
|
||||
// - this is a required input
|
||||
if (string.IsNullOrWhiteSpace(Activity.Address1))
|
||||
{
|
||||
Toast.ShowError("Kunde adresse er ufuldstændig.");
|
||||
Toaster.ShowError("Kunde adresse er ufuldstændig.");
|
||||
return;
|
||||
}
|
||||
//
|
||||
// validate org number
|
||||
// - this is a required input
|
||||
// - must validate according to country rules.
|
||||
if (!VatUtils.ValidateFormat(Company.CountryCode, Activity.VatNumber))
|
||||
{
|
||||
Toaster.ShowError("Firma registreringsnummer er ikke korrekt.");
|
||||
return;
|
||||
}
|
||||
// validate input according to status
|
||||
switch (Activity.ActivityStatusEnum)
|
||||
{
|
||||
// don't accept order with no lines
|
||||
case "order" when DraftProvider.Draft.Items.Count == 0:
|
||||
Toast.ShowError("Ved bestilling skal der være en eller flere linjer i kladden.");
|
||||
Toaster.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):
|
||||
Toast.ShowError("Ved bestilling til ny kunde skal telefon nummer angives.");
|
||||
case "order" when Company.Account is "NY" or "" && string.IsNullOrWhiteSpace(Activity.Phone):
|
||||
Toaster.ShowError("Ved bestilling til ny kunde skal telefon nummer angives.");
|
||||
return;
|
||||
// verify email address is a valid address
|
||||
case "quote" when !Utils.IsValidEmail(Activity.Email):
|
||||
Toast.ShowError("Ved tilbud skal en gyldig email adresse angives.");
|
||||
Toaster.ShowError("Ved tilbud skal en gyldig email adresse angives.");
|
||||
return;
|
||||
}
|
||||
// raise working flag
|
||||
|
@ -324,15 +424,16 @@ 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;
|
||||
Activity.OrderMessage = $"Telefonnr. opdateret.\n{Activity.OrderMessage}";
|
||||
await CompanyRepo.UpdateErpData(Company.CompanyId, Company);
|
||||
}
|
||||
// begin assembling activity
|
||||
Activity.ActivityDate = $"{SelectedDate:yyyy-MM-dd}";
|
||||
Activity.OurRef = Activity.ActivityTypeEnum switch
|
||||
{
|
||||
"phone" => $"T:{ThisUserInfo.FullName.Split(" ")[0]}",
|
||||
"onSite" => $"B:{ThisUserInfo.FullName.Split(" ")[0]}",
|
||||
"phone" => $"T:{SalesRep.FullName.Split(" ")[0]}",
|
||||
"onSite" => $"B:{SalesRep.FullName.Split(" ")[0]}",
|
||||
_ => ""
|
||||
};
|
||||
if (Activity.Express)
|
||||
|
@ -361,22 +462,22 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
// debug logging
|
||||
Logger.LogDebug("CrmNewActivityPage => \n {}", JsonSerializer.Serialize(Activity));
|
||||
// post to api
|
||||
var result = await AdvisorActivityRepo.CreateActivity(Activity);
|
||||
var result = await ActivityRepo.CreateActivity(Activity);
|
||||
// debug logging
|
||||
Logger.LogDebug("ApiResponseView => \n {}", JsonSerializer.Serialize(result));
|
||||
// show result message
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
Toast.ShowSuccess($"{result.Message}",
|
||||
Toaster.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
|
||||
Working = false;
|
||||
// show error message
|
||||
Toast.ShowError(result.Message, "ORDRE FEJL");
|
||||
Toaster.ShowError(result.Message, "ORDRE FEJL");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -446,12 +547,11 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
DraftProvider.Draft.Items = new List<DraftItem>();
|
||||
}
|
||||
|
||||
ButtonText = Activity.ActivityStatusEnum switch
|
||||
ButtonText = Activity.ActivityStatusEnum.ToLower() switch
|
||||
{
|
||||
"noSale" => "Gem Besøg",
|
||||
"order" => "Gem Bestilling",
|
||||
"quote" => "Gem Tilbud",
|
||||
_ => ButtonText
|
||||
"nosale" => "Gem Besøg",
|
||||
"order" => "Send Bestilling",
|
||||
"quote" => "Send Tilbud"
|
||||
};
|
||||
|
||||
// InvalidCanvas = InvalidActivityType;
|
||||
|
@ -477,10 +577,20 @@ public partial class AdvisorCreateActivityPage : IDisposable
|
|||
{
|
||||
if (string.IsNullOrEmpty(Activity.ActivityTypeEnum) && !ReportClosed)
|
||||
{
|
||||
Toast.ShowWarning("Aktivitet type kan ikke være tom");
|
||||
Toaster.ShowWarning("Aktivitet type kan ikke være tom");
|
||||
PoFormInvalid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Activity.ActivityStatusEnum.ToLower() is "order" or "quote"
|
||||
&& Company.CountryCode.ToLower() == "se"
|
||||
&& VatUtils.SanitizeVatNumber(Activity.VatNumber).Length < 10)
|
||||
{
|
||||
ShowOrgWarning();
|
||||
PoFormInvalid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
PoFormInvalid = false;
|
||||
ActivityContext.OnFieldChanged -= HandleFieldChanged;
|
||||
ActivityContext.OnValidationStateChanged -= ValidationChanged;
|
|
@ -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/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/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)
|
||||
{
|
|
@ -25,15 +25,15 @@ using Wonky.Entity.Views;
|
|||
|
||||
namespace Wonky.Client.Pages;
|
||||
|
||||
public partial class AdvisorTodayActivityListPage : IDisposable
|
||||
public partial class AdvisorActivityTodayListPage : IDisposable
|
||||
{
|
||||
[Inject] public UserProfileService UserProfileService { get; set; }
|
||||
[Inject] public ILogger<AdvisorTodayActivityListPage> Logger { get; set; }
|
||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] public NavigationManager Navigator { get; set; }
|
||||
[Inject] public IAdvisorActivityRepository AdvisorActivityRepo { get; set; }
|
||||
[Inject] public IAdvisorReportRepository AdvisorReportRepo { get; set; }
|
||||
[Inject] public IToastService Toaster { get; set; }
|
||||
[Inject] private UserProfileService UserProfileService { get; set; }
|
||||
[Inject] private ILogger<AdvisorActivityTodayListPage> Logger { get; set; }
|
||||
[Inject] private HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] private NavigationManager Navigator { get; set; }
|
||||
[Inject] private IAdvisorActivityRepository AdvisorActivityRepo { get; set; }
|
||||
[Inject] private IAdvisorReportRepository AdvisorReportRepo { get; set; }
|
||||
[Inject] private IToastService Toaster { get; set; }
|
||||
private ReportStatusView? ReportStatusView { get; set; } = new();
|
||||
private UserPref UserPref { get; set; } = new();
|
||||
private DateTime SelectedDate { get; set; }
|
|
@ -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">
|
|
@ -29,15 +29,15 @@ using Wonky.Entity.Views;
|
|||
|
||||
namespace Wonky.Client.Pages;
|
||||
|
||||
public partial class AdvisorViewActivityPage : IDisposable
|
||||
public partial class AdvisorActivityViewPage : 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 ILogger<AdvisorViewActivityPage> Logger { get; set; }
|
||||
[Inject] public IToastService Toaster { get; set; }
|
||||
[Inject] public NavigationManager Navigator { get; set; }
|
||||
[Inject] private HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] private IAdvisorActivityRepository AdvisorActivityRepo { get; set; }
|
||||
[Inject] private ILogger<AdvisorActivityViewPage> Logger { get; set; }
|
||||
[Inject] private IToastService Toaster { get; set; }
|
||||
[Inject] private NavigationManager Navigator { get; set; }
|
||||
private ReportItemView ReportItem { get; set; } = new();
|
||||
private ActivityOfficeNote Note { get; set; } = new();
|
||||
private EditContext NoteContext { get; set; }
|
||||
|
@ -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()
|
|
@ -1,52 +0,0 @@
|
|||
@*
|
||||
// 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.Client.Components
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@attribute [Authorize(Roles = "Advisor")]
|
||||
@page "/price-catalog"
|
||||
|
||||
<div class="sticky-top bg-dark rounded-2 px-3">
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-sm-2">
|
||||
<CatalogGroupComponent OnChanged="SetGroupCol"/>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<CatalogSearchComponent OnChanged="SetSearchCol"/>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<CatalogSearchPhraseComponent OnChanged="SetSearchPhrase"/>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<CatalogSortComponent OnChanged="SetSortCol"/>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<PageSizeComponent OnChanged="SetPageSize"/>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<PaginationComponent MetaData="MetaInfo" Spread="2" SelectedPage="SetSelectedPage"/>
|
||||
</div>
|
||||
<div class="col-sm-2 text-end">
|
||||
<a class="btn btn-secondary" href="/print/catalog"><i class="bi-printer"></i> Udskriv</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<CatalogListComponent ItemList="Items"/>
|
||||
@if (Working)
|
||||
{
|
||||
<WorkingThreeDots />
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Blazored.LocalStorage;
|
||||
using Wonky.Client.HttpInterceptors;
|
||||
using Wonky.Client.HttpRepository;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Wonky.Client.Components;
|
||||
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 AdvisorCatalogPage : IDisposable
|
||||
{
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] public IAdvisorCatalogRepository ItemRepo { get; set; }
|
||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] public UserProfileService ProfileService { get; set; }
|
||||
private List<SalesItemView> Items { get; set; } = new();
|
||||
private MetaData MetaInfo { get; set; } = new();
|
||||
private CatalogPaging _page = new();
|
||||
private UserPref Prefs = new();
|
||||
private UserInfoView UserInfo { get; set; } = new();
|
||||
private bool Working { get; set; } = true;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Prefs = await ProfileService.GetPreferences();
|
||||
UserInfo = await Storage.GetItemAsync<UserInfoView>("_xu");
|
||||
|
||||
_page.OrderBy = Prefs.ItemSort;
|
||||
_page.SearchColumn = Prefs.ItemSearch;
|
||||
_page.PageSize = Convert.ToInt32(Prefs.PageSize);
|
||||
|
||||
Interceptor.RegisterEvent();
|
||||
Interceptor.RegisterBeforeSendEvent();
|
||||
|
||||
await FetchSalesItems();
|
||||
}
|
||||
|
||||
private async Task SetSearchPhrase(string searchTerm)
|
||||
{
|
||||
Items = new List<SalesItemView>();
|
||||
_page.PageNumber = 1;
|
||||
_page.SearchTerm = searchTerm;
|
||||
await FetchSalesItems();
|
||||
}
|
||||
|
||||
private async Task SetPageSize(string pageSize)
|
||||
{
|
||||
Items = new List<SalesItemView>();
|
||||
_page.PageSize = Convert.ToInt32(pageSize);
|
||||
_page.PageNumber = 1;
|
||||
await FetchSalesItems();
|
||||
}
|
||||
|
||||
private async Task SetSearchCol(string columnName)
|
||||
{
|
||||
Items = new List<SalesItemView>();
|
||||
_page.PageNumber = 1;
|
||||
_page.SearchColumn = columnName;
|
||||
await FetchSalesItems();
|
||||
}
|
||||
|
||||
private async Task SetSortCol(string orderBy)
|
||||
{
|
||||
Items = new List<SalesItemView>();
|
||||
_page.OrderBy = orderBy;
|
||||
await FetchSalesItems();
|
||||
}
|
||||
|
||||
private async Task SetSelectedPage(int page)
|
||||
{
|
||||
Items = new List<SalesItemView>();
|
||||
_page.PageNumber = page;
|
||||
await FetchSalesItems();
|
||||
}
|
||||
|
||||
private async Task SetGroupCol(string groupFilter)
|
||||
{
|
||||
Items = new List<SalesItemView>();
|
||||
_page.PageNumber = 1;
|
||||
_page.SelectGroup = groupFilter;
|
||||
await FetchSalesItems();
|
||||
}
|
||||
|
||||
private async Task FetchSalesItems()
|
||||
{
|
||||
Working = true;
|
||||
var pagingResponse = await ItemRepo.GetSalesItemsPaged(_page);
|
||||
Working = false;
|
||||
Items = pagingResponse.Items!;
|
||||
MetaInfo = pagingResponse.MetaData;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void Dispose() => Interceptor.DisposeEvent();
|
||||
|
||||
}
|
|
@ -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,70 +29,14 @@
|
|||
<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>
|
||||
|
||||
<div class="list-group">
|
||||
<div class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h4>Dato</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Demo</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Salg</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Note /Kontor</h4>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Note /Selv</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (Activities.Any())
|
||||
{
|
||||
@foreach (var activity in Activities)
|
||||
{
|
||||
<div class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@activity.OrderDate
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.Demo
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.Sales
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.OfficeNote
|
||||
</div>
|
||||
<div class="col">
|
||||
@activity.CrmNote
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
Ingen data
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<CustomerVisitListComponent Activities="Activities" />
|
||||
}
|
||||
@if (Working)
|
||||
{
|
||||
|
|
|
@ -28,9 +28,9 @@ namespace Wonky.Client.Pages;
|
|||
public partial class AdvisorCustomerActivityListPage : IDisposable
|
||||
{
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
[Inject] public HttpInterceptorService _interceptor { get; set; }
|
||||
[Inject] public IAdvisorActivityRepository AdvisorActivityRepo { get; set; }
|
||||
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||
[Inject] private HttpInterceptorService _interceptor { get; set; }
|
||||
[Inject] private IAdvisorActivityRepository AdvisorActivityRepo { get; set; }
|
||||
[Inject] private IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||
private List<ReportItemView> Activities { get; set; } = new();
|
||||
private CompanyDto Company { get; set; } = new();
|
||||
private bool Working { get; set; } = true;
|
||||
|
|
|
@ -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">
|
||||
|
@ -30,7 +31,20 @@
|
|||
<div class="row g-2">
|
||||
@* vat lookup *@
|
||||
<div class="col-sm-12 text-end">
|
||||
<button type="button" class="btn btn-primary" @onclick="CallVatLookupModal">CVR opslag</button>
|
||||
<div class="d-grid mx-auto">
|
||||
@switch (Company.CountryCode)
|
||||
{
|
||||
case "dk":
|
||||
<button type="button" class="btn btn-info" @onclick="CallVatLookupModal"><i class="bi-search"></i> Firma søgning</button>
|
||||
break;
|
||||
case "no":
|
||||
<a class="btn btn-info" href="https://brreg.no/" target="_blank"><i class="bi-search"></i> Firma søgning</a>
|
||||
break;
|
||||
case "se":
|
||||
<a class="btn btn-info" href="https://www.allabolag.se/@(string.IsNullOrWhiteSpace(Company.Name) ? "" : "what/@Company.Name")" target="_blank"><i class="bi-search"></i> Firma søgning</a>
|
||||
break;
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@* entity name *@
|
||||
<label for="name" class="col-sm-1 col-form-label-sm">Navn</label>
|
||||
|
@ -69,7 +83,7 @@
|
|||
<ValidationMessage For="@(() => Company.City)"></ValidationMessage>
|
||||
</div>
|
||||
@* entity vat number *@
|
||||
<label for="vatNumber" class="col-sm-1 col-form-label-sm">Moms Nr</label>
|
||||
<label for="vatNumber" class="col-sm-1 col-form-label-sm">Cvr/Org Nr.</label>
|
||||
<div class="col-sm-3">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">
|
||||
|
@ -99,7 +113,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<hr class="mb-3"/>
|
||||
<div class="row g-2">
|
||||
<div class="row g-2 mb-3">
|
||||
<label for="note" class="col-sm-1 col-form-label-sm">OBS</label>
|
||||
<div class="col-sm-5">
|
||||
<InputText id="note" class="form-control" @bind-Value="Company.Note"/>
|
||||
|
@ -124,7 +138,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-12 text-end">
|
||||
<div class="col-sm-12 d-grid mx-auto">
|
||||
<button type="submit" class="btn btn-success" disabled="@FormInvalid">Opret</button>
|
||||
</div>
|
||||
</div>
|
|
@ -37,15 +37,15 @@ using Wonky.Entity.Views;
|
|||
|
||||
namespace Wonky.Client.Pages
|
||||
{
|
||||
public partial class AdvisorCreateCustomerPage : IDisposable
|
||||
public partial class AdvisorCustomerCreatePage : IDisposable
|
||||
{
|
||||
[Inject] public IToastService Toaster { get; set; }
|
||||
[Inject] public ILogger<AdvisorCreateCustomerPage> Logger { get; set; }
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] public NavigationManager Navigator { get; set; }
|
||||
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] public VatInfoLookupService VatService { get; set; }
|
||||
[Inject] private IToastService Toaster { get; set; }
|
||||
[Inject] private ILogger<AdvisorCustomerCreatePage> Logger { get; set; }
|
||||
[Inject] private ILocalStorageService Storage { get; set; }
|
||||
[Inject] private NavigationManager Navigator { get; set; }
|
||||
[Inject] private IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||
[Inject] private HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] private VatInfoLookupService VatService { get; set; }
|
||||
private EditContext CompanyContext { get; set; }
|
||||
private CompanyDto Company { get; set; } = new();
|
||||
private VirkRegInfo CompanyRegInfo { get; set; } = new();
|
||||
|
@ -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
|
||||
{
|
|
@ -17,24 +17,24 @@
|
|||
|
||||
@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-right"></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>
|
||||
|
||||
<CustomerInventoryListComponent OnReorderSelected="OnReorderCallback" CompanyId="@CompanyId" Inventory="@Inventory"/>
|
||||
|
||||
<InventoryReorderModal OnSelected="@OnSelectedItem" CompanyId="@CompanyId" SalesItem="@SalesItem" @ref="ReorderModal"/>
|
||||
<CustomerInventoryReorderModalOverlay OnSelected="@OnSelectedItem" CompanyId="@CompanyId" SalesItem="@SalesItem" @ref="CustomerInventoryReorderOverlay"/>
|
||||
|
||||
@if (Working)
|
||||
{
|
||||
|
|
|
@ -28,13 +28,13 @@ namespace Wonky.Client.Pages;
|
|||
|
||||
public partial class AdvisorCustomerInventoryListPage : IDisposable
|
||||
{
|
||||
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] public IToastService Toaster { get; set; }
|
||||
[Inject] public ILogger<AdvisorCustomerInventoryListPage> Logger { get; set; }
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] public IAdvisorCatalogRepository AdvisorCatalogRepo { get; set; }
|
||||
[Inject] private IAdvisorCustomerHistoryRepository CustomerHistory { get; set; }
|
||||
[Inject] private IAdvisorCustomerRepository Customers { get; set; }
|
||||
[Inject] private HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] private IToastService Toaster { get; set; }
|
||||
[Inject] private ILogger<AdvisorCustomerInventoryListPage> Logger { get; set; }
|
||||
[Inject] private ILocalStorageService Storage { get; set; }
|
||||
[Inject] private ICountryCatalogRepository Catalog { get; set; }
|
||||
|
||||
[CascadingParameter] public DraftStateProvider DraftStateProvider { get; set; } = new();
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
|
@ -44,7 +44,7 @@ public partial class AdvisorCustomerInventoryListPage : IDisposable
|
|||
private CompanyDto Company { get; set; } = new();
|
||||
private bool Working { get; set; } = true;
|
||||
private SalesItemView SalesItem { get; set; } = new();
|
||||
private InventoryReorderModal ReorderModal { get; set; } = new();
|
||||
private CustomerInventoryReorderModalOverlay CustomerInventoryReorderOverlay { get; set; } = new();
|
||||
private List<ProductInventoryView> Inventory { get; set; } = new();
|
||||
|
||||
|
||||
|
@ -53,7 +53,7 @@ public partial class AdvisorCustomerInventoryListPage : IDisposable
|
|||
Interceptor.RegisterEvent();
|
||||
Interceptor.RegisterBeforeSendEvent();
|
||||
|
||||
Company = await CompanyRepo.GetCompanyById(CompanyId);
|
||||
Company = await Customers.GetCompanyById(CompanyId);
|
||||
|
||||
// fetch product inventory
|
||||
await FetchProductInventory();
|
||||
|
@ -64,8 +64,8 @@ public partial class AdvisorCustomerInventoryListPage : IDisposable
|
|||
private async Task OnReorderCallback(string sku)
|
||||
{
|
||||
// fetch item from http repo
|
||||
SalesItem = await AdvisorCatalogRepo.GetSalesItemSku(Company.CountryCode.ToLower(), sku);
|
||||
ReorderModal.Show();
|
||||
SalesItem = await Catalog.GetSalesItemSku(Company.CountryCode.ToLower(), sku);
|
||||
CustomerInventoryReorderOverlay.Show();
|
||||
}
|
||||
|
||||
private async Task OnSelectedItem(DraftItem draftItem)
|
||||
|
@ -92,7 +92,7 @@ public partial class AdvisorCustomerInventoryListPage : IDisposable
|
|||
}
|
||||
Logger.LogDebug("pulling products from backend");
|
||||
// fetch product history
|
||||
Inventory = await HistoryRepo.FetchInventory(CompanyId);
|
||||
Inventory = await CustomerHistory.FetchInventory(CompanyId);
|
||||
// default sort order by description
|
||||
if (Inventory.Any())
|
||||
Inventory = Inventory.OrderBy(x => x.Description).ToList();
|
||||
|
|
|
@ -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,14 +26,14 @@
|
|||
<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"/>
|
||||
<InvoiceViewModal CompanyId="@_companyId" InvoiceId="@InvoiceId" @ref="InvoiceView" />
|
||||
<CustomerInvoiceViewModalOverlay CompanyId="@_companyId" InvoiceId="@InvoiceId" @ref="CustomerInvoiceView" />
|
||||
}
|
||||
|
||||
@if (Working)
|
||||
|
|
|
@ -15,17 +15,17 @@ namespace Wonky.Client.Pages;
|
|||
public partial class AdvisorCustomerInvoiceListPage : IDisposable
|
||||
{
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||
[Inject] public IToastService Toaster { get; set; }
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] public ILogger<AdvisorCustomerInvoiceListPage> Logger { get; set; }
|
||||
[Inject] private IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||
[Inject] private HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] private IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
|
||||
[Inject] private IToastService Toaster { get; set; }
|
||||
[Inject] private ILocalStorageService Storage { get; set; }
|
||||
[Inject] private ILogger<AdvisorCustomerInvoiceListPage> Logger { get; set; }
|
||||
private InvoiceListView CompanyInvoices { get; set; } = new();
|
||||
private CompanyDto Company { get; set; } = new();
|
||||
private bool Working { get; set; }
|
||||
private InvoiceViewModal InvoiceView { get; set; } = new();
|
||||
private CustomerInvoiceViewModalOverlay CustomerInvoiceView { get; set; } = new();
|
||||
private string InvoiceId { get; set; } = "";
|
||||
private bool Working { get; set; }
|
||||
private bool AllSet { get; set; }
|
||||
private string _companyId = "";
|
||||
|
||||
|
@ -63,7 +63,7 @@ public partial class AdvisorCustomerInvoiceListPage : IDisposable
|
|||
private void CallInvoiceModal(string invoiceId)
|
||||
{
|
||||
InvoiceId = invoiceId;
|
||||
InvoiceView.Show();
|
||||
CustomerInvoiceView.Show();
|
||||
}
|
||||
|
||||
private async Task<InvoiceListView> FetchCompanyInvoices()
|
||||
|
@ -80,13 +80,18 @@ public partial class AdvisorCustomerInvoiceListPage : IDisposable
|
|||
}
|
||||
Logger.LogDebug("pulling invoices from backend");
|
||||
// pull invoices
|
||||
var invoices = await HistoryRepo.FetchInvoiceList(_companyId);
|
||||
var companyInvoices = await HistoryRepo.FetchInvoiceList(_companyId);
|
||||
if (companyInvoices.Invoices.Any())
|
||||
companyInvoices.Invoices = companyInvoices.Invoices
|
||||
.OrderByDescending(x => x.DocumentDate)
|
||||
.ToList();
|
||||
|
||||
// send invoices to storage
|
||||
await Storage.SetItemAsync($"{_companyId}-invoices", invoices);
|
||||
await Storage.SetItemAsync($"{_companyId}-invoices", companyInvoices);
|
||||
await Storage.SetItemAsync($"{_companyId}-iDate", $"{DateTime.Now:yyyy-MM-dd}");
|
||||
Logger.LogDebug("return invoices from backend");
|
||||
Working = false;
|
||||
return invoices;
|
||||
return companyInvoices;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
@ -17,39 +17,46 @@
|
|||
|
||||
@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" />
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<button type button class="btn btn-warning @(@IncludeFolded ? "active" : "")"
|
||||
data-bs-toggle="button" aria-pressed="@IncludeFolded" @onclick="OnFoldedClick">
|
||||
@ButtonFoldedText
|
||||
</button>
|
||||
|
||||
@*
|
||||
<div class="form-check">
|
||||
<input type="checkbox" id="folded" class="form-check-input" checked="@IncludeFolded" @onclick="OnFoldedClick" >
|
||||
<label for="folded" class="form-check-label">Ophørte</label>
|
||||
</div>
|
||||
*@
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<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)
|
||||
{
|
||||
|
|
|
@ -30,11 +30,11 @@ namespace Wonky.Client.Pages
|
|||
{
|
||||
public partial class AdvisorCustomerListPage : IDisposable
|
||||
{
|
||||
[Inject] public ILocalStorageService Storage { get; set; }
|
||||
[Inject] public UserProfileService ProfileService { get; set; }
|
||||
[Inject] public IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||
[Inject] public HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] public NavigationManager Navigator { get; set; }
|
||||
[Inject] private ILocalStorageService Storage { get; set; }
|
||||
[Inject] private UserProfileService ProfileService { get; set; }
|
||||
[Inject] private IAdvisorCustomerRepository CompanyRepo { get; set; }
|
||||
[Inject] private HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] private NavigationManager Navigator { get; set; }
|
||||
private List<CompanyDto> Companies { get; set; } = new();
|
||||
private UserPref Prefs { get; set; } = new();
|
||||
private UserInfoView UserInfo { get; set; } = new();
|
||||
|
@ -43,6 +43,7 @@ namespace Wonky.Client.Pages
|
|||
private bool Working { get; set; } = true;
|
||||
private MetaData PageData { get; set; } = new();
|
||||
private CustomerPaging Paging { get; set; } = new();
|
||||
private string ButtonFoldedText { get; set; } = "Vis Ophørte";
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
|
@ -66,24 +67,26 @@ namespace Wonky.Client.Pages
|
|||
Paging.SearchTerm = SavedSearch;
|
||||
|
||||
// get companies
|
||||
await FetchCompanies();
|
||||
await FetchCustomers();
|
||||
Working = false;
|
||||
}
|
||||
|
||||
private async Task OnFoldedClick()
|
||||
{
|
||||
Working = true;
|
||||
IncludeFolded = !IncludeFolded;
|
||||
ButtonFoldedText = IncludeFolded ? "Vis Aktive" : "Vis Ophørte";
|
||||
Companies = new List<CompanyDto>();
|
||||
Paging.PageNumber = 1;
|
||||
Paging.HasFolded = IncludeFolded ? 1 : 0;
|
||||
await FetchCompanies();
|
||||
await FetchCustomers();
|
||||
}
|
||||
|
||||
private async Task SelectedPage(int page)
|
||||
{
|
||||
Companies = new List<CompanyDto>();
|
||||
Paging.PageNumber = page;
|
||||
await FetchCompanies();
|
||||
await FetchCustomers();
|
||||
}
|
||||
|
||||
private async Task SetSearchCol(string searchColumn)
|
||||
|
@ -91,14 +94,14 @@ namespace Wonky.Client.Pages
|
|||
Companies = new List<CompanyDto>();
|
||||
Paging.SearchColumn = searchColumn;
|
||||
Paging.PageNumber = 1;
|
||||
await FetchCompanies();
|
||||
await FetchCustomers();
|
||||
}
|
||||
private async Task SetPageSize(string pageSize)
|
||||
{
|
||||
Companies = new List<CompanyDto>();
|
||||
Paging.PageSize = Convert.ToInt32(pageSize);
|
||||
Paging.PageNumber = 1;
|
||||
await FetchCompanies();
|
||||
await FetchCustomers();
|
||||
}
|
||||
|
||||
private async Task SetSearchPhrase(string searchTerm)
|
||||
|
@ -106,14 +109,14 @@ namespace Wonky.Client.Pages
|
|||
Companies = new List<CompanyDto>();
|
||||
Paging.PageNumber = 1;
|
||||
Paging.SearchTerm = searchTerm;
|
||||
await FetchCompanies();
|
||||
await FetchCustomers();
|
||||
}
|
||||
|
||||
private async Task SetSortCol(string orderBy)
|
||||
{
|
||||
Companies = new List<CompanyDto>();
|
||||
Paging.OrderBy = orderBy;
|
||||
await FetchCompanies();
|
||||
await FetchCustomers();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -126,10 +129,10 @@ namespace Wonky.Client.Pages
|
|||
await CompanyRepo.DeleteCompany(companyId);
|
||||
if (Paging.PageNumber > 1 && Companies.Count == 1)
|
||||
Paging.PageNumber--;
|
||||
await FetchCompanies();
|
||||
await FetchCustomers();
|
||||
}
|
||||
|
||||
private async Task FetchCompanies()
|
||||
private async Task FetchCustomers()
|
||||
{
|
||||
Working = true;
|
||||
var pageRes = await CompanyRepo.GetCompanies(Paging);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue