This commit is contained in:
Frede Hundewadt 2022-04-13 15:16:35 +02:00
parent 5c52f97ce9
commit be1b81382e
12 changed files with 82 additions and 67 deletions

View file

@ -48,7 +48,7 @@ namespace Wonky.Client.AuthProviders
return _anonymous;
// create an authorized user
var userInfo = await _storage.GetItemAsync<UserInfoDto>("_ux");
var userInfo = await _storage.GetItemAsync<UserInfo>("_ux");
if (userInfo == null)
return _anonymous;
@ -83,7 +83,7 @@ namespace Wonky.Client.AuthProviders
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
// create an authorized user
var userInfo = await _storage.GetItemAsync<UserInfoDto>("_ux");
var userInfo = await _storage.GetItemAsync<UserInfo>("_ux");
var exp = await _storage.GetItemAsync<string>("_ex");
var roles = ExtractRoles(userInfo);
var claims = new List<Claim>
@ -109,7 +109,7 @@ namespace Wonky.Client.AuthProviders
NotifyAuthenticationStateChanged(authState);
}
private static IEnumerable<string> ExtractRoles(UserInfoDto userInfo)
private static IEnumerable<string> ExtractRoles(UserInfo userInfo)
{
var roles = new List<string>();
if (userInfo.IsAdmin)

View file

@ -17,7 +17,7 @@
<span class="version">@Name</span> <span class="version">@Version</span>@if(IsBeta){<span class="version">-beta</span>}
@code
{
private const string Version = "0.2.23";
private const string Version = "0.2.24";
private const string Name = "wwo";
private const bool IsBeta = true;
}

View file

@ -7,6 +7,7 @@ public class DraftItem
public int Quantity { get; set; }
public SalesItemDto Item { get; set; }
public decimal Price { get; set; }
public decimal Discount { get; set; }
public decimal Total
{
@ -16,7 +17,7 @@ public class DraftItem
if (string.IsNullOrWhiteSpace(price))
price = Item.Rates[0].Rate;
Price = Convert.ToDecimal(price);
return Price * Quantity;
return (Price - Price * Discount / 100) * Quantity;
}
}
}

View file

@ -21,28 +21,29 @@ namespace Wonky.Client.Models
{
public class PurchaseOrder
{
public int ActivityId { get; set; }
public string ActivityId { get; set; } = "";
public string CrmCompanyKey { get; set; } = "";
[Required(ErrorMessage = "Sælger skal udfyldes")] public string SalesRep { get; set; } = "";
[Required(ErrorMessage = "Konto skal udfyldes")] public string Account { get; set; } = "";
[Required(ErrorMessage = "Navn skal udfyldes")] public string Name { get; set; } = "";
[Required(ErrorMessage = "Bynavn skal udfyldes")] public string City { get; set; }= "";
[Required(ErrorMessage = "Postnummer skal udfyldes")] public string ZipCode { get; set; } = "";
public string SalesRep { get; set; } = "";
public string Account { get; set; } = "";
public string Name { get; set; } = "";
public string City { get; set; }= "";
public string ZipCode { get; set; } = "";
[Required(ErrorMessage = "Vælg aktivitet")] public string ActivityType { get; set; } = "";
public string OurRef { get; set; } = ""; // sales rep
public string OurRef { get; set; } = "";
public string Address { get; set; } = "";
public string Address2 { get; set; } = "";
public string Phone { get; set; } = "";
public string EMail { get; set; } = "";
// Form entries
public bool CheckDate { get; set; }
public DateTime ActivityDate { get; set; }
public string Demo { get; set; } = "";
public string VatNumber { get; set; } = "";
public string ReferenceNumber { get; set; } = "";
public string YourRef { get; set; } = "";
[MaxLength(255, ErrorMessage = "Du kan højst bruge 255 tegn")]public string YourRef { get; set; } = "";
[MaxLength(255, ErrorMessage = "Du kan højst bruge 255 tegn")] public string OrderMessage { get; set; } = "";
public string CrmNote { get; set; } = "";
// form entry
// Delivery address form entries
public string DlvName { get; set; } = "";
public string DlvAddress1 { get; set; } = "";
public string DlvAddress2 { get; set; } = "";

View file

@ -54,7 +54,7 @@ namespace Wonky.Client.Pages
_editContext = new EditContext(_companyDto);
_editContext.OnFieldChanged += HandleFieldChanged;
var ux = await StorageService.GetItemAsync<UserInfoDto>("_ux");
var ux = await StorageService.GetItemAsync<UserInfo>("_ux");
_companyDto.SalesRepId = ux.Id;
_companyDto.CountryCode = ux.CountryCode;
Interceptor.RegisterEvent();

View file

@ -54,18 +54,21 @@ namespace Wonky.Client.Pages
private async Task SelectedPage(int page)
{
Companies = new List<CompanyDto>();
_paging.PageNumber = page;
await GetCompanies();
}
private async Task SetSearchCol(string searchColumn)
{
Companies = new List<CompanyDto>();
_paging.SearchColumn = searchColumn;
_paging.PageNumber = 1;
await GetCompanies();
}
private async Task SetPageSize(string pageSize)
{
Companies = new List<CompanyDto>();
_paging.PageSize = Convert.ToInt32(pageSize);
_paging.PageNumber = 1;
await GetCompanies();
@ -73,6 +76,7 @@ namespace Wonky.Client.Pages
private async Task SetSearchPhrase(string searchTerm)
{
Companies = new List<CompanyDto>();
_paging.PageNumber = 1;
_paging.SearchTerm = searchTerm;
await GetCompanies();
@ -80,12 +84,14 @@ namespace Wonky.Client.Pages
private async Task SetSortCol(string orderBy)
{
Companies = new List<CompanyDto>();
_paging.OrderBy = orderBy;
await GetCompanies();
}
private async Task DeleteCompany(string companyId)
{
Companies = new List<CompanyDto>();
await CompanyRepo.DeleteCompany(companyId);
if (_paging.PageNumber > 1 && Companies.Count == 1)
_paging.PageNumber--;

View file

@ -22,7 +22,7 @@
@if (_company != null)
{
<h2>@_purchaseOrder.Name</h2>
<EditForm EditContext="_editContext" OnValidSubmit="CreateActivity" >
<EditForm EditContext="_editContext" OnValidSubmit="CreateActivity">
<DataAnnotationsValidator/>
<div class="accordion-flush" id="crmActivity">
@* Section for activity header *@
@ -38,27 +38,32 @@
aria-labelledby="activityHeader" data-bs-parent="#crmActivity">
<div class="accordion-body">
<div class="row mb-1">
<label for="activityDate" class="col-form-label col-md-2">Næste besøg</label>
<div class="col-md-3">
<InputDate id="activityDate" class="form-control" @bind-Value="@(ActivityDate)"/>
<label for="activityDate" class="col-sm-2 col-md-2 col-form-label">Aktivitet</label>
<div class="col-sm-3 col-md-3">
<InputDate id="activityDate" class="form-control" @bind-Value="@(_purchaseOrder.ActivityDate)"/>
</div>
<label for="activityType" class="col-md-2 col-form-label">Aktivitet</label>
<div class="col-md-2">
<div class="col-sm-3 col-md-3">
<select id="activityType" class="form-select" @bind-value="@_purchaseOrder.ActivityType" @bind-value:event="oninput">
<option value="" selected></option>
<option value="" selected>vælg</option>
<option value="onSite">Besøg</option>
<option value="phone">Telefon</option>
<option value="canvas">Kanvas</option>
</select>
</div>
<label for="account" class="col-md-2 col-form-label">Konto</label>
<div class="col-md-2">
<div class="col-sm-2 col-md-2">
<InputCheckbox id="checkDate" class="form-check-input" @bind-Value="@_purchaseOrder.CheckDate"></InputCheckbox>
<label for="checkDate" class="form-check-label">Godkendt</label>
</div>
</div>
<div class="row mb-1">
<label for="account" class="col-sm-2 col-md-2 col-form-label">Konto</label>
<div class="col-sm-4 col-md-4">
<InputText id="account" class="form-control" @bind-Value="_purchaseOrder.Account" readonly/>
<ValidationMessage For="@(() => _purchaseOrder.Account)"></ValidationMessage>
</div>
<label for="salesRep" class="col-md-2 col-form-label">Sælger</label>
<div class="col-md-2">
<label for="salesRep" class="col-sm-2 col-md-2 col-form-label">Sælger</label>
<div class="col-sm-4 col-md-4">
<InputText id="salesRep" class="form-control" @bind-Value="_purchaseOrder.SalesRep" readonly/>
<ValidationMessage For="@(() => _purchaseOrder.SalesRep)"></ValidationMessage>
</div>
@ -69,13 +74,6 @@
<InputText id="demo" class="form-control" @bind-Value="_purchaseOrder.Demo"/>
</div>
</div>
<div class="row mb-1">
<label for="vatNumber" class="col-md-2 col-form-label">CVR nummer</label>
<div class="col-md-10">
<InputText id="vatNumber" class="form-control" @bind-Value="_purchaseOrder.VatNumber"/>
<ValidationMessage For="@(() => _purchaseOrder.VatNumber)"></ValidationMessage>
</div>
</div>
<div class="row mb-1">
<label for="referenceNumber" class="col-md-2 col-form-label">Rekvisition</label>
<div class="col-md-10">
@ -91,7 +89,7 @@
</div>
</div>
<div class="row mb-1">
<label for="orderMessage" class="col-md-2 col-form-label">Besked til kontoret</label>
<label for="orderMessage" class="col-md-2 col-form-label">Eksp. note</label>
<div class="col-md-10">
<InputText id="orderMessage" class="form-control" @bind-Value="_purchaseOrder.OrderMessage"/>
<ValidationMessage For="@(() => _purchaseOrder.OrderMessage)"></ValidationMessage>
@ -188,10 +186,9 @@
<table class="table table-hover table-striped justify-content-center">
<thead>
<tr>
<th scope="col" style="width: 50%;">Navn</th>
<th scope="col" style="width: 30%;" class="text-nowrap">Varenr</th>
<th scope="col" style="width: 20%">Stk / Pris</th>
<th scope="col"></th>
<th scope="col">Navn</th>
<th scope="col" class="text-nowrap">Varenr</th>
<th scope="col">Stk / Pris</th>
</tr>
</thead>
<tbody>
@ -207,13 +204,11 @@
<li class="list-group-item d-flex justify-content-between align-items-end">
<div class="text-sm-start px-2">@rate.Quantity</div>
<div class="text-sm-end">@rate.Rate</div>
<button class="btn btn-primary" @onclick="@(() => SelectItem(item.ItemId, rate.Quantity, rate.Rate))">Vælg</button>
</li>
}
</ul>
</td>
<td>
<button class="btn btn-primary" @onclick="@(() => SelectItem(item.ItemId))">Vælg</button>
</td>
</tr>
}
</tbody>
@ -243,6 +238,9 @@
<div class="col fw-bold">
Pris
</div>
<div class="col">
Rabat
</div>
<div class="col">
</div>
@ -260,6 +258,9 @@
<div class="col">
<input class="form-control" type="number" @bind-value="@Price"/>
</div>
<div class="col">
<input class="form-control" type="number" @bind-value="@Discount"/>
</div>
<div class="col">
<button class="btn btn-info" @onclick="@(() => AddItem(_selectedItem))">Læg til</button>
</div>
@ -336,9 +337,9 @@
<div class="row mt-2 mb-2">
<div class="col">
<a class="btn btn-primary" href="/company/@_company.CompanyId">Tilbage</a>
<button type="button" class="btn btn-success" @onclick="CreateActivity" disabled="@_poFormInvalid">Kanvas</button>
<button type="button" class="btn btn-success" @onclick="CreateActivityOffer" disabled="@(_poFormInvalid || DraftStateProvider.Draft.Items.Count == 0)">Tilbud</button>
<button type="button" class="btn btn-success" @onclick="CreateActivityOrder" disabled="@(_poFormInvalid || DraftStateProvider.Draft.Items.Count == 0)">Bestilling</button>
<button type="button" class="btn btn-dark" @onclick="CreateActivity" disabled="@(_poFormInvalid || !_purchaseOrder.CheckDate)">Kanvas</button>
<button type="button" class="btn btn-warning" @onclick="CreateActivityOffer" disabled="@(_poFormInvalid || DraftStateProvider.Draft.Items.Count == 0 || !_purchaseOrder.CheckDate)">Tilbud</button>
<button type="button" class="btn btn-success" @onclick="CreateActivityOrder" disabled="@(_poFormInvalid || DraftStateProvider.Draft.Items.Count == 0 || !_purchaseOrder.CheckDate)">Bestilling</button>
</div>
</div>
</EditForm>

View file

@ -13,9 +13,6 @@
// 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 Blazored.Toast.Services;
using Wonky.Client.Helpers;
@ -33,12 +30,6 @@ namespace Wonky.Client.Pages;
public partial class CrmActivityCreate : IDisposable
{
private SalesItemDto _selectedItem { get; set; } = new();
private List<SalesItemDto> SalesItems { get; set; } = new();
private MetaData _meta { get; set; } = new();
private Preferences _prefs { get; set; } = new();
[Parameter] public string CompanyId { get; set; }
[CascadingParameter] DraftStateProvider DraftStateProvider { get; set; }
[Inject] private ISalesItemHttpRepository ItemRepo { get; set; }
[Inject] private ICompanyHttpRepository CompanyRepo { get; set; }
[Inject] private HttpInterceptorService Interceptor { get; set; }
@ -47,7 +38,12 @@ public partial class CrmActivityCreate : IDisposable
[Inject] public NavigationManager NavigationManager { get; set; }
[Inject] public ILocalStorageService StorageService { get; set; }
[Inject] public ISalesItemHttpRepository SalesItemRepo { get; set; }
[Parameter] public string CompanyId { get; set; }
[CascadingParameter] DraftStateProvider DraftStateProvider { get; set; }
private SalesItemDto _selectedItem { get; set; } = new();
private List<SalesItemDto> SalesItems { get; set; } = new();
private MetaData _meta { get; set; } = new();
private Preferences _prefs { get; set; } = new();
private PurchaseOrder _purchaseOrder = new ();
private CompanyDto _company = new();
private EditContext _editContext;
@ -58,7 +54,7 @@ public partial class CrmActivityCreate : IDisposable
private bool ShowSearchView;
private string Quantity = "1";
private string Price = "0";
private DateTime ActivityDate { get; set; }
private string Discount = "0";
protected override async Task OnInitializedAsync()
{
@ -67,13 +63,14 @@ public partial class CrmActivityCreate : IDisposable
_prefs = await UserPrefs.GetPreferences();
_paging.SearchColumn = _prefs.ItemSearch;
await GetSalesItems();
var ux = await StorageService.GetItemAsync<UserInfoDto>("_ux");
var ux = await StorageService.GetItemAsync<UserInfo>("_ux");
_company = await CompanyRepo.GetCompanyById(CompanyId);
_editContext = new EditContext(_purchaseOrder);
_editContext.OnFieldChanged += HandleFieldChanged;
// set up indexdb identification
_purchaseOrder.ActivityId = Utils.GetHashFromNow();
_purchaseOrder.ActivityId = CompanyId;
_purchaseOrder.CrmCompanyKey = CompanyId;
// permanent identifications
_purchaseOrder.SalesRep = ux.Adviser;
@ -101,12 +98,12 @@ public partial class CrmActivityCreate : IDisposable
await DraftStateProvider.DeleteDraftAsync();
}
private void SelectItem(string itemId)
private void SelectItem(string itemId, string quantity, string price)
{
ShowItem = true;
_selectedItem = (from x in SalesItems where x.ItemId == itemId select x).First();
Price = _selectedItem.Rates[0].Rate;
Quantity = "1";
Price = price;
Quantity = quantity;
}
private async Task AddItem(SalesItemDto salesItem)
@ -133,12 +130,14 @@ public partial class CrmActivityCreate : IDisposable
}
private async Task SetItemGroup(string groupFilter)
{
SalesItems = new List<SalesItemDto>();
_paging.PageNumber = 1;
_paging.SelectGroup = groupFilter;
await GetSalesItems();
}
private async Task SetSearchCol(string columnName)
{
SalesItems = new List<SalesItemDto>();
_paging.PageNumber = 1;
_paging.SearchTerm = "";
_paging.SearchColumn = columnName;
@ -146,6 +145,7 @@ public partial class CrmActivityCreate : IDisposable
}
private async Task SetSortCol(string searchTerm)
{
SalesItems = new List<SalesItemDto>();
_paging.PageNumber = 1;
_paging.SearchTerm = searchTerm;
await GetSalesItems();

View file

@ -52,6 +52,7 @@ public partial class SalesItemCatalog : IDisposable
private async Task SelectedPage(int page)
{
SalesItemList = new List<SalesItemDto>();
_paging.PageNumber = page;
await GetSalesItems();
}
@ -65,6 +66,7 @@ public partial class SalesItemCatalog : IDisposable
private async Task SetPageSize(string pageSize)
{
SalesItemList = new List<SalesItemDto>();
_paging.PageSize = Convert.ToInt32(pageSize);
_paging.PageNumber = 1;
await GetSalesItems();
@ -72,18 +74,21 @@ public partial class SalesItemCatalog : IDisposable
private async Task SetItemGroup(string groupFilter)
{
SalesItemList = new List<SalesItemDto>();
_paging.PageNumber = 1;
_paging.SelectGroup = groupFilter;
await GetSalesItems();
}
private async Task SetSearchCol(string columnName)
{
SalesItemList = new List<SalesItemDto>();
_paging.PageNumber = 1;
_paging.SearchColumn = columnName;
await GetSalesItems();
}
private async Task SetSearchPhrase(string searchTerm)
{
SalesItemList = new List<SalesItemDto>();
_paging.PageNumber = 1;
_paging.SearchTerm = searchTerm;
await GetSalesItems();
@ -91,6 +96,7 @@ public partial class SalesItemCatalog : IDisposable
private async Task SetSortCol(string orderBy)
{
SalesItemList = new List<SalesItemDto>();
_paging.OrderBy = orderBy;
await GetSalesItems();
}

View file

@ -140,14 +140,14 @@ namespace Wonky.Client.Services
_client.DefaultRequestHeaders.Authorization = null;
}
public async Task<UserInfoDto> UserInfo(bool write = false)
public async Task<UserInfo> UserInfo(bool write = false)
{
var infoResponse = await _client.GetAsync(_apiConfig.Value.UserInfo);
var infoContent = await infoResponse.Content.ReadAsStringAsync();
var userInfo = JsonSerializer.Deserialize<UserInfoDto>(infoContent, _options);
var userInfo = JsonSerializer.Deserialize<UserInfo>(infoContent, _options);
if(write)
await _localStorage.SetItemAsync("_ux", userInfo);
return userInfo ?? new UserInfoDto();
return userInfo ?? new UserInfo();
}
}

View file

@ -24,7 +24,7 @@ namespace Wonky.Client.Services
Task<AuthResponseDto> Login(UserAuthenticationDto userAuth);
Task Logout();
Task<string> RefreshToken();
Task<UserInfoDto> UserInfo(bool write = false);
Task<UserInfo> UserInfo(bool write = false);
}
}

View file

@ -17,7 +17,7 @@ using System.Text.Json.Serialization;
namespace Wonky.Entity.DTO;
public class UserInfoDto
public class UserInfo
{
[JsonPropertyName("Id")] public string Id { get; set; } = "";
[JsonPropertyName("adviser")] public string Adviser { get; set; } = "";