wip - price list - krv

This commit is contained in:
Frede Hundewadt 2022-08-02 07:05:20 +02:00
parent bc6fd7f987
commit 8604803634
19 changed files with 544 additions and 304 deletions

View file

@ -26,12 +26,15 @@ namespace Wonky.Client.Components
[Parameter] public EventCallback<string> OnChanged { get; set; }
[Parameter] public string SavedSearch { get; set; } = string.Empty;
protected override void OnParametersSet()
{
_searchTerm = SavedSearch;
}
protected override void OnInitialized()
{
if (string.IsNullOrWhiteSpace(SavedSearch))
if (string.IsNullOrWhiteSpace(_searchTerm))
return;
_searchTerm = SavedSearch;
OnSearchChanged();
}

View file

@ -21,10 +21,10 @@ namespace Wonky.Client.HttpRepository;
public interface IUserHttpRepository
{
Task<List<UserListAdminView>> GetAdvisors();
Task<AdminUserInfoDto> GetAdvisorInfo(string userId);
Task<UserInfoDto> GetAdvisorInfo(string userId);
Task UpdateAdvisor(string userId, UserUpdateDto model);
Task<List<UserListAdminView>> GetAdminUsers();
Task<AdminUserInfoDto> GetAdminUserInfo(string userId);
Task<UserInfoDto> GetAdminUserInfo(string userId);
Task UpdateAdminUser(string userId, UserUpdateDto model);
Task ResetUserPassword(string userId, string newPasswd, string confirmPasswd);
}

View file

@ -52,9 +52,9 @@ public class UserHttpRepository : IUserHttpRepository
return await _client.GetFromJsonAsync<List<UserListAdminView>>(_api.AdminUser);
}
public async Task<AdminUserInfoDto> GetAdvisorInfo(string userId)
public async Task<UserInfoDto> GetAdvisorInfo(string userId)
{
return await _client.GetFromJsonAsync<AdminUserInfoDto>($"{_api.AdminUser}/{userId}");
return await _client.GetFromJsonAsync<UserInfoDto>($"{_api.AdminUser}/{userId}");
}
public async Task UpdateAdvisor(string userId, UserUpdateDto model)
@ -67,9 +67,9 @@ public class UserHttpRepository : IUserHttpRepository
return await _client.GetFromJsonAsync<List<UserListAdminView>>(_api.AdminOffice);
}
public async Task<AdminUserInfoDto> GetAdminUserInfo(string userId)
public async Task<UserInfoDto> GetAdminUserInfo(string userId)
{
return await _client.GetFromJsonAsync<AdminUserInfoDto>($"{_api.AdminOffice}/{userId}");
return await _client.GetFromJsonAsync<UserInfoDto>($"{_api.AdminOffice}/{userId}");
}
public async Task UpdateAdminUser(string userId, UserUpdateDto model)

View file

@ -20,6 +20,7 @@
@attribute [Authorize(Roles = "Advisor")]
@using Wonky.Client.Components
<PriceListModal OnSelectedItem="SelectSku" @ref="_priceList"/>
<div class="card">
<div class="card-header">
<div class="row align-items-center">
@ -121,8 +122,8 @@
</div>
<div class="accordion" id="crmActivity">
@* Order lines *@
<div class="accordion-item" style="@(_draft.ActivityStatusEnum is "order" or "quote" ? "display: block" : "display:none")">
@* Order lines *@
<div class="accordion-item" style="@(_draft.ActivityStatusEnum is "order" or "quote" ? "display: block" : "display:none")">
<h2 class="accordion-header" id="catalogHeader">
<button class="accordion-button collapsed bg-light" type="button"
data-bs-toggle="collapse" data-bs-target="#catalogBody"
@ -158,30 +159,33 @@
<tbody>
@if (DraftStateProvider != null && DraftStateProvider.Draft.Items.Count > 0)
{
@foreach (var cItem in DraftStateProvider.Draft.Items)
@foreach (var cartItem in DraftStateProvider.Draft.Items)
{
<tr>
<td>@cItem.Item.Name</td>
<td>@cItem.Item.Sku</td>
<td class="text-end">@cItem.Quantity</td>
<td class="text-end">@cItem.Price</td>
<td class="text-end">@cItem.LineTotal</td>
<td class="text-center">
<input type="checkbox" checked="@cItem.Sas" disabled/>
<td class="align-middle">@cartItem.Item.Name</td>
<td class="align-middle">@cartItem.Item.Sku</td>
<td class="align-middle text-end">@cartItem.Quantity</td>
<td class="align-middle text-end">@cartItem.Price</td>
<td class="align-middle text-end">@cartItem.LineTotal</td>
<td class="align-middle text-center">
<input type="checkbox" checked="@cartItem.Sas" disabled/>
</td>
<td class="text-end">
<button type="button" class="btn btn-danger" @onclick="@(() => RemoveItem(@cItem))">Slet Linje</button>
<td class="align-middle text-end">
<button type="button" class="btn btn-danger" @onclick="@(() => RemoveItem(cartItem))">Slet Linje</button>
</td>
</tr>
}
}
<tr>
<td colspan="3"></td>
<td class="align-middle text-black text-end fw-bold">Total</td>
<td class="align-middle text-black text-end fw-bold">@DraftStateProvider.Draft.Total</td>
<td></td>
<td></td>
<td></td>
<td class="text-black text-end fw-bold">Total</td>
<td class="text-black text-end fw-bold">@DraftStateProvider.Draft.Total</td>
<td></td>
<td class="align-middle text-end">
<button class="btn btn-primary" type="button" @onclick="CallPriceListModal">
<i class="oi oi-plus"></i>
</button>
</td>
</tr>
</tbody>
</table>
@ -208,20 +212,20 @@
</thead>
<tbody>
<tr>
<td>
<td class="align-middle">
<input type="number" class="form-control" @bind-value="@Quantity"/>
</td>
<td>
<td class="align-middle">
<input type="number" class="form-control" @bind-value="@Price"/>
</td>
<td>
<td class="align-middle">
<input type="number" class="form-control" @bind-value="@Discount"/>
</td>
<td class="align-content-center justify-content-center">
<td class="align-middle align-content-center justify-content-center">
<input type="checkbox" class="form-check" @bind-value="@Sas"/>
</td>
<td>@_selectedItem.Sku</td>
<td>
<td class="align-middle">@_selectedItem.Sku</td>
<td class="align-middle">
<button type="button" class="btn btn-warning text-nowrap d-block" @onclick="@(() => AddItem(_selectedItem))">bestil @Quantity stk @_selectedItem.Name</button>
</td>
</tr>
@ -230,81 +234,11 @@
}
</div>
</div>
<div class="row">
<div class="col">
@* catalog *@
<div class="sticky-top bg-dark rounded-2 px-3 pt-3">
<div class="row mb-2">
@* <div class="col"> *@
@* <ItemGroupComponent OnChanged="SetItemGroup"/> *@
@* </div> *@
<div class="col">
<ItemSearchComponent OnChanged="SetSearchCol"/>
</div>
<div class="col">
<SearchPhraseComponent OnChanged="SetSearchPhrase"/>
</div>
<div class="col">
<ItemSortComponent OnChanged="SetSortCol"/>
</div>
<div class="col">
<PageSizeComponent OnChanged="SetPageSize" />
</div>
</div>
@* <div class="row"> *@
@* <div class="col"> *@
@* <PaginationComponent MetaData="_metaData" Spread="2" SelectedPage="SelectedPage"></PaginationComponent> *@
@* </div> *@
@* </div> *@
</div>
@if (_catalog.Any())
{
<table class="table table-hover table-striped justify-content-center">
<thead>
<tr class="bg-dark bg-opacity-50 text-white rounded-2">
<th scope="col">Navn</th>
<th scope="col" class="text-nowrap">Varenr</th>
<th scope="col" class="text-nowrap">Fork</th>
<th scope="col">Stk / Pris</th>
</tr>
</thead>
<tbody>
@foreach (var item in _catalog)
{
<tr>
<td>@item.Name</td>
<td>@item.Sku</td>
<td>@item.ShortName</td>
<td>
<ul class="list-group">
@foreach (var rate in item.Rates)
{
<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>
<a class="btn btn-primary" @onclick="@(() => SelectItem(item.ItemId, rate.Quantity, rate.Rate))">
Vælg
</a>
</li>
}
</ul>
</td>
</tr>
}
</tbody>
</table>
}
else
{
<div>Der er ingen data</div>
}
</div>
</div>
</div>
</div>
</div>
@* Delivery address *@
<div class="accordion-item" style="@(_draft.ActivityStatusEnum == "order" ? "display: block" : "display:none")">
@* Delivery address *@
<div class="accordion-item" style="@(_draft.ActivityStatusEnum == "order" ? "display: block" : "display:none")">
<h2 class="accordion-header" id="deliveryHeader">
<button class="accordion-button collapsed bg-light" type="button" data-bs-toggle="collapse" data-bs-target="#deliveryBody" aria-expanded="false" aria-controls="deliveryBody">
Leveringsadresse
@ -345,14 +279,14 @@
</div>
</div>
</div>
</div>
</div>
</div>
</EditForm>
</div>
<div class="card-footer">
@if (HideButtons)
{
<LoaderThreeDots />
<LoaderThreeDots/>
}
else
{

View file

@ -17,7 +17,6 @@ using System.Globalization;
using System.Text.Json;
using Blazored.LocalStorage;
using Blazored.Toast.Services;
using Wonky.Client.Helpers;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository;
using Wonky.Client.Models;
@ -26,7 +25,6 @@ using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.Services;
using Wonky.Client.Shared;
using Wonky.Entity.DTO;
using Wonky.Entity.Requests;
using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
@ -48,14 +46,12 @@ public partial class ActivityNewVisitPage : IDisposable
[Inject] private IActivityHttpRepository _activityRepo { get; set; }
[Inject] private IReportHttpRepository _reportRepo { get; set; }
// variables
private PriceListModal _priceList { get; set; }
private readonly JsonSerializerOptions? _options = new JsonSerializerOptions{PropertyNameCaseInsensitive = true};
private SalesItemView _selectedItem { get; set; } = new();
private List<SalesItemView> _catalog { get; set; } = new();
private MetaData _metaData { get; set; } = new();
private Preferences _prefs { get; set; } = new();
private ActivityDto _draft { get; set; } = new();
private CompanyDto _company = new();
private CatalogPagingParams _paging = new();
private EditContext _editContext { get; set; }
private bool _poFormInvalid { get; set; } = true;
private bool ShowItem { get; set; }
@ -100,11 +96,6 @@ public partial class ActivityNewVisitPage : IDisposable
_draft.ActivityDate = $"{_workDate:yyyy-MM-dd}" ;
_paging.SearchColumn = string.IsNullOrWhiteSpace(_prefs.ItemSearch) ? "name" : _prefs.ItemSearch;
_paging.PageSize = Convert.ToInt32(_prefs.PageSize);
await GetSalesItems();
_ux = await _storage.GetItemAsync<UserInfoView>("_xu");
_company = await _companyRepo.GetCompanyById(CompanyId);
@ -146,7 +137,18 @@ public partial class ActivityNewVisitPage : IDisposable
_draft.DlvCity = _company.City;
}
private void CallPriceListModal()
{
_priceList.Show();
}
private async Task SelectSku(SelectedSku sku)
{
ShowItem = true;
Console.WriteLine($"XTextPriceList => sku: {JsonSerializer.Serialize(sku)}");
_selectedItem = await _itemRepo.GetSalesItem(sku.ItemId);
Price = sku.Rate;
Quantity = sku.Quantity;
}
private void SetWorkDate(string workDate)
{
_selectedDate = workDate;
@ -220,14 +222,6 @@ public partial class ActivityNewVisitPage : IDisposable
await DraftStateProvider.DeleteDraftAsync();
}
private void SelectItem(string itemId, string quantity, string price)
{
ShowItem = true;
_selectedItem = (from x in _catalog where x.ItemId == itemId select x).First();
Price = price;
Quantity = quantity;
}
private async Task AddItem(SalesItemView salesItem)
{
ShowItem = false;
@ -257,55 +251,6 @@ public partial class ActivityNewVisitPage : IDisposable
// save the remaining draft
await DraftStateProvider.SaveChangesAsync();
}
private async Task SetItemGroup(string groupFilter)
{
_catalog = new List<SalesItemView>();
_paging.PageNumber = 1;
_paging.SelectGroup = groupFilter;
await GetSalesItems();
}
private async Task SetSearchCol(string columnName)
{
_catalog = new List<SalesItemView>();
_paging.PageNumber = 1;
_paging.SearchTerm = "";
_paging.SearchColumn = columnName;
await GetSalesItems();
}
private async Task SetSortCol(string orderBy)
{
_catalog = new List<SalesItemView>();
_paging.OrderBy = orderBy;
await GetSalesItems();
}
private async Task SetSearchPhrase(string searchTerm)
{
_catalog = new List<SalesItemView>();
_paging.PageNumber = 1;
_paging.SearchTerm = searchTerm;
await GetSalesItems();
}
private async Task SelectedPage(int page)
{
_catalog = new List<SalesItemView>();
_paging.PageNumber = page;
await GetSalesItems();
}
private async Task SetPageSize(string pageSize)
{
_catalog = new List<SalesItemView>();
_paging.PageSize = Convert.ToInt32(pageSize);
_paging.PageNumber = 1;
await GetSalesItems();
}
private async Task GetSalesItems()
{
var response = await _itemRepo.GetSalesItemsPaged(_paging);
_catalog = response.Items!;
_metaData = response.MetaData;
}
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
{

View file

@ -21,7 +21,7 @@
<div class="card">
<div class="card-header bg-dark text-white">
<div class="card-title">
<h3>@AdminUserInfo.FirstName @AdminUserInfo.LastName Kunder</h3>
<h3>@UserInfoDto.FirstName @UserInfoDto.LastName Kunder</h3>
</div>
</div>
<div class="card-body">

View file

@ -35,7 +35,7 @@ public partial class AllCustomersListPage : IDisposable
private CompanyPagingParams _paging = new();
private Preferences _preferences { get; set; } = new();
private string _savedSearch { get; set; } = "";
private AdminUserInfoDto AdminUserInfo { get; set; } = new();
private UserInfoDto UserInfoDto { get; set; } = new();
private List<CompanyDto> _companyList { get; set; } = new();
protected override async Task OnInitializedAsync()

View file

@ -25,7 +25,7 @@
<h3>Bruger info</h3>
</div>
<div class="card-body">
@if (AdminUserInfo != null)
@if (UserInfoDto != null)
{
<EditForm EditContext="_editContext" OnValidSubmit="UpdateAdvisor">
<DataAnnotationsValidator/>
@ -70,7 +70,7 @@
Sælgernr.
</th>
<td>
@AdminUserInfo.Advisor
@UserInfoDto.Advisor
</td>
<th scope="col">
Landekode

View file

@ -33,7 +33,7 @@ public partial class CrmUserViewPage : IDisposable
[Inject] private ILogger<CrmUserViewPage> _logger { get; set; }
[Inject] private NavigationManager _navigator { get; set; }
[Inject] private IToastService _toast { get; set; }
private AdminUserInfoDto AdminUserInfo { get; set; } = new();
private UserInfoDto UserInfoDto { get; set; } = new();
private EditContext _editContext { get; set; }
private UserUpdateDto _updateInfo { get; set; } = new();
private AdminResetPasswordDto _passwords { get; set; } = new();
@ -53,14 +53,14 @@ public partial class CrmUserViewPage : IDisposable
_interceptor.RegisterEvent();
_interceptor.RegisterBeforeSendEvent();
AdminUserInfo = await _userRepo.GetAdvisorInfo(UserId);
UserInfoDto = await _userRepo.GetAdvisorInfo(UserId);
_updateInfo.Email = AdminUserInfo.Email;
_updateInfo.CountryCode = AdminUserInfo.CountryCode;
_updateInfo.FirstName = AdminUserInfo.FirstName;
_updateInfo.LastName = AdminUserInfo.LastName;
_updateInfo.PhoneNumber = AdminUserInfo.PhoneNumber;
_updateInfo.LockoutEnabled = AdminUserInfo.LockoutEnabled;
_updateInfo.Email = UserInfoDto.Email;
_updateInfo.CountryCode = UserInfoDto.CountryCode;
_updateInfo.FirstName = UserInfoDto.FirstName;
_updateInfo.LastName = UserInfoDto.LastName;
_updateInfo.PhoneNumber = UserInfoDto.PhoneNumber;
_updateInfo.LockoutEnabled = UserInfoDto.LockoutEnabled;
_passwdContext.OnFieldChanged += PwHandleFieldChanged;
_passwdContext.OnValidationStateChanged += PwValidationChanged;

View file

@ -27,7 +27,7 @@
<div class="card-header bg-dark text-white">
<h3>@_company.Account - @_company.Name</h3>
</div>
@if (_dk && !_validVat)
@if (_dk)
{
<div class="card-body">
<VatAddressInputComponent Address="vatAddress" OnValidSubmit="GetInfoFromAddress"/>
@ -196,19 +196,19 @@
<div class="card-footer">
<div class="row">
<div class="col">
<a class="btn btn-light border-dark" href="/companies">Oversigt</a>
<a class="btn btn-light border-dark d-block" href="/companies">Oversigt</a>
</div>
<div class="col">
<a class="btn btn-light border-dark" href="/companies/@_company.CompanyId/h/i">Produktkøb</a>
<a class="btn btn-light border-dark d-block" href="/companies/@_company.CompanyId/h/i">Produktkøb</a>
</div>
<div class="col">
<a class="btn btn-light border-dark" href="/companies/@_company.CompanyId/h/p">Varelinjer</a>
<a class="btn btn-light border-dark d-block" href="/companies/@_company.CompanyId/h/p">Varelinjer</a>
</div>
<div class="col">
<a class="btn btn-light border-dark" href="/companies/@_company.CompanyId/workplaces">Kemi</a>
<a class="btn btn-light border-dark d-block" href="/companies/@_company.CompanyId/workplaces">Kemi</a>
</div>
<div class="col">
<button type="submit" class="btn btn-light border-dark">Gem</button>
<button type="submit" class="btn btn-light border-dark d-block">Gem</button>
</div>
<div class="col">
<ActivityButton ActionLink="@_actionLink"

View file

@ -24,6 +24,6 @@
</div>
</div>
<div class="card-body">
<CompanyTableComponent Companies="_companyList"></CompanyTableComponent>
<CustomerTableComponent Companies="_companyList"></CustomerTableComponent>
</div>
</div>

View file

@ -20,7 +20,7 @@ using Wonky.Entity.DTO;
namespace Wonky.Client.Pages;
public partial class AdminCompanyListPage
public partial class OfficeCustomerListPage
{
[Parameter] public string UserId { get; set; } = "";
[Parameter] public string CountryCode { get; set; } = "";

View file

@ -0,0 +1,182 @@
@using Microsoft.AspNetCore.Authorization
@using Wonky.Client.Components
@attribute [Authorize(Roles = "Office,Warehouse")]
@page "/office/customers/{CompanyId}/orders/new"
<EditForm EditContext="_editContext">
<DataAnnotationsValidator/>
<div class="row mb-1">
<label for="name" class="col-md-1 col-form-label">Navn</label>
<div class="col-md-5">
<InputText id="name" class="form-control" @bind-Value="_draft.Name" readonly/>
</div>
<label for="account" class="col-md-1 col-form-label">Konto</label>
<div class="col-md-2">
<InputText id="account" class="form-control" @bind-Value="_draft.Account" readonly/>
</div>
<label for="phone" class="col-md-1 col-form-label">Tlf</label>
<div class="col-md-2">
<InputText id="phone" class="form-control" @bind-Value="_draft.Phone"/>
</div>
</div>
<div class="row mb-1">
<label for="referenceNumber" class="col-md-2 col-form-label">Rekvisition</label>
<div class="col-md-4">
<InputText id="referenceNumber" class="form-control" @bind-Value="_draft.ReferenceNumber"/>
<ValidationMessage For="@(() => _draft.ReferenceNumber)"></ValidationMessage>
</div>
<label for="yourRef" class="col-md-2 col-form-label">Indkøber</label>
<div class="col-md-4">
<InputText id="yourRef" class="form-control" @bind-Value="_draft.YourRef"/>
<ValidationMessage For="@(() => _draft.YourRef)"></ValidationMessage>
</div>
</div>
<div class="row mb-1">
<label for="orderMessage" class="col-md-2 col-form-label">Ordre notat</label>
<div class="col-md-10">
<InputTextArea id="orderMessage" class="form-control" @bind-Value="_draft.OrderMessage"/>
<ValidationMessage For="@(() => _draft.OrderMessage)"></ValidationMessage>
</div>
</div>
<div class="row">
<div class="col">
<table class="sticky-top table table-hover table-striped table-bordered">
<thead>
<tr class="bg-dark text-white">
<th scope="col" colspan="6">
Ordrekladde <span class="mx-2 draft-expires-msg">Global kladde (udløber efter @(DraftStateProvider.Draft.TimeToLiveInSeconds / 60)m inaktivitet)</span>
</th>
<th scope="col" class="text-end">
<button type="button" class="btn btn-danger btn-sm" @onclick="@DeleteDraft" disabled="@(DraftStateProvider.Draft.Items.Count == 0)">Slet kladde</button>
</th>
</tr>
<tr class="bg-dark opacity-75 text-white">
<th scope="col">Navn</th>
<th scope="col" class="text-nowrap">Varenr</th>
<th scope="col" class="text-end">Antal</th>
<th scope="col" class="text-end">Enhedspris</th>
<th scope="col" class="text-end">Linjesum</th>
<th scope="col" class="text-end">SAS</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@if (DraftStateProvider != null && DraftStateProvider.Draft.Items.Count > 0)
{
@foreach (var cartItem in DraftStateProvider.Draft.Items)
{
<tr>
<td class="align-middle">@cartItem.Item.Name</td>
<td class="align-middle">@cartItem.Item.Sku</td>
<td class="align-middle text-end">@cartItem.Quantity</td>
<td class="align-middle text-end">@cartItem.Price</td>
<td class="align-middle text-end">@cartItem.LineTotal</td>
<td class="align-middle text-center">
<input type="checkbox" checked="@cartItem.Sas" disabled/>
</td>
<td class="align-middle text-end">
<button type="button" class="btn btn-danger" @onclick="@(() => RemoveItem(cartItem))">Slet Linje</button>
</td>
</tr>
}
}
<tr>
<td colspan="3"></td>
<td class="align-middle text-black text-end fw-bold">Total</td>
<td class="align-middle text-black text-end fw-bold">@DraftStateProvider.Draft.Total</td>
<td></td>
<td class="align-middle text-end">
<button class="btn btn-primary" type="button" @onclick="CallPriceListModal">
<i class="oi oi-plus"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col">
@* draft line *@
@if (_selectedItem != null && ShowItem)
{
<table id="draft-line" class="table table-bordered">
<thead>
<tr class="bg-dark text-white">
<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 class="align-content-center justify-content-center" scope="col">SAS</th>
<th scope="col">Varenr.</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr>
<td class="align-middle">
<input type="number" class="form-control" @bind-value="@Quantity"/>
</td>
<td class="align-middle">
<input type="number" class="form-control" @bind-value="@Price"/>
</td>
<td class="align-middle">
<input type="number" class="form-control" @bind-value="@Discount"/>
</td>
<td class="align-middle align-content-center justify-content-center">
<input type="checkbox" class="form-check" @bind-value="@Sas"/>
</td>
<td class="align-middle">@_selectedItem.Sku</td>
<td class="align-middle">
<button type="button" class="btn btn-warning text-nowrap d-block" @onclick="@(() => AddItem(_selectedItem))">bestil @Quantity stk @_selectedItem.Name</button>
</td>
</tr>
</tbody>
</table>
}
</div>
</div>
<div id="dlvAddress">
<div class="row mb-1">
<div class="col-md-4">
<InputText id="dlvName" class="form-control" @bind-Value="_draft.DlvName"/>
</div>
<div class="col-md-4">
<InputText id="dlvAddress1" class="form-control" @bind-Value="_draft.DlvAddress1"/>
</div>
<div class="col-md-4">
<InputText id="dlvAddress2" class="form-control" @bind-Value="_draft.DlvAddress2"/>
</div>
</div>
<div class="row mb-1">
<div class="col-md-4">
<InputText id="dlvZipCode" class="form-control" @bind-Value="_draft.DlvZipCode"/>
</div>
<div class="col-md-4">
<InputText id="dlvCity" class="form-control" @bind-Value="_draft.DlvCity"/>
</div>
</div>
</div>
</EditForm>
<div class="card-footer">
@if (HideButton)
{
<LoaderThreeDots/>
}
else
{
<div class="row mt-2 mb-2">
<div class="col text-end">
<button type="button" class="btn btn-primary" @onclick="CreateOrder" disabled="@FormInvalid">Ordre order</button>
</div>
</div>
}
</div>

View file

@ -0,0 +1,177 @@
using System.Globalization;
using System.Text.Json;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository;
using Wonky.Client.Models;
using Wonky.Client.Shared;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
namespace Wonky.Client.Pages;
public partial class OfficeNewOrderPage : IDisposable
{
[CascadingParameter] DraftStateProvider DraftStateProvider { get; set; }
[Parameter] public string CompanyId { get; set; }
[Inject] private HttpInterceptorService _interceptor { get; set; }
[Inject] private ICompanyHttpRepository _companyRepo { get; set; }
[Inject] private IUserHttpRepository _userRepo { get; set; }
[Inject] private ISalesItemHttpRepository _itemRepo { get; set; }
[Inject] private IActivityHttpRepository _activityRepo { get; set; }
private PriceListModal _priceList { get; set; } = new();
private CompanyDto _company { get; set; } = new();
private EditContext _editContext { get; set; }
private ActivityDto _draft { get; set; } = new();
private UserInfoDto _userInfo { get; set; } = new();
private SalesItemView _selectedItem { get; set; } = new();
private string Rate { get; set; } = "0";
private string Quantity { get; set; } = "1";
private string Price { get; set; } = "0";
private string Discount { get; set; } = "0";
private bool ShowItem { get; set; }
private bool Sas { get; set; }
private bool FormInvalid { get; set; } = true;
private bool HideButton { get; set; }
protected override async Task OnParametersSetAsync()
{
_interceptor.RegisterEvent();
_interceptor.RegisterBeforeSendEvent();
_company = await _companyRepo.GetCompanyById(CompanyId);
_userInfo = await _userRepo.GetAdvisorInfo(_company.SalesRepId);
}
protected override async Task OnInitializedAsync()
{
_editContext = new EditContext(_draft);
_editContext.OnFieldChanged += HandleFieldChanged;
_editContext.OnValidationStateChanged += ValidationChanged;
_interceptor.RegisterEvent();
_interceptor.RegisterBeforeSendEvent();
_draft.ActivityDate = $"{DateTime.Now:yyyy-MM-dd}" ;
// variable to validate if customer needs phone number update
// _phone = _company.Phone;
if (string.IsNullOrWhiteSpace(_company.Phone)
&& !string.IsNullOrWhiteSpace(_company.Account)
&& _company.Account != "NY" && _company.Account.Length > 7)
{
_company.Phone = _company.Account[..8];
}
_draft.ActivityStatusEnum = "order";
_draft.ActivityTypeEnum = "phone";
// set up identification
_draft.CompanyId = _company.CompanyId;
_draft.BcId = _company.BcId;
_draft.SalesRepId = _userInfo.UserId;
_draft.ActivityStatusEnum = "noSale";
_draft.VisitTypeEnum = _company.Account is "" or "NY" ? "new" : "recall";
// permanent identifications
_draft.SalesRep = _userInfo.Advisor;
_draft.Account = _company.Account;
_draft.VatNumber = _company.VatNumber;
_draft.Email = _company.Email;
_draft.Phone = _company.Phone;
_draft.Mobile = _company.Mobile;
_draft.Name = _company.Name;
_draft.Address1 = _company.Address1;
_draft.Address2 = _company.Address2;
_draft.ZipCode = _company.ZipCode;
_draft.City = _company.City;
_draft.DlvName = _company.Name;
_draft.DlvAddress1 = _company.Address1;
_draft.DlvAddress2 = _company.Address2;
_draft.DlvZipCode = _company.ZipCode;
_draft.DlvCity = _company.City;
}
private void CallPriceListModal()
{
_priceList.Show();
}
private async Task SelectSku(SelectedSku sku)
{
ShowItem = true;
_selectedItem = await _itemRepo.GetSalesItem(sku.ItemId);
Price = sku.Rate;
Quantity = sku.Quantity;
}
private async Task DeleteDraft()
{
await DraftStateProvider.DeleteDraftAsync();
}
private async Task CreateOrder()
{
await _activityRepo.CreateActivity(_draft);
}
private async Task AddItem(SalesItemView salesItem)
{
ShowItem = false;
// create a new cart item
var item = new DraftItem
{
Item = salesItem,
Quantity = Convert.ToInt32(Quantity),
Price = Convert.ToDecimal(Price, CultureInfo.InvariantCulture),
Discount = Convert.ToDecimal(Discount, CultureInfo.InvariantCulture),
Sas = Sas
};
// reset internals to initial state
Sas = false;
Quantity = "1";
Price = "0";
Discount = "0";
// add it to the cart
DraftStateProvider.Draft.Items.Add(item);
// save the item using the CartStateProvider's save method
await DraftStateProvider.SaveChangesAsync();
}
private async Task RemoveItem(DraftItem item)
{
// remove item
DraftStateProvider.Draft.Items.Remove(item);
// save the remaining draft
await DraftStateProvider.SaveChangesAsync();
}
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
{
if (DraftStateProvider.Draft.Items.Count == 0)
{
FormInvalid = true;
return;
}
FormInvalid = !_editContext.Validate();
StateHasChanged();
}
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
{
FormInvalid = false;
_editContext.OnFieldChanged -= HandleFieldChanged;
_editContext.OnValidationStateChanged -= ValidationChanged;
_editContext = new EditContext(_draft);
_editContext.OnFieldChanged += HandleFieldChanged;
_editContext.OnValidationStateChanged += ValidationChanged;
}
public void Dispose()
{
_interceptor.DisposeEvent();
_editContext.OnFieldChanged -= HandleFieldChanged;
_editContext.OnValidationStateChanged -= ValidationChanged;
}
}

View file

@ -33,7 +33,7 @@
<div class="col-md-2 justify-content-center">
@if (_working)
{
<LoaderBallTriangle/>
<LoaderThreeDots />
}
</div>
</div>

View file

@ -116,4 +116,3 @@
}
</div>
</div>
<PriceListModal OnSelectedItem="SelectSku" @ref="_priceList" />

View file

@ -49,7 +49,7 @@
<AuthorizeView Roles="Admin,Warehouse,Office">
<div class="nav-item px-3">
<NavLink class="nav-link ps-2" href="/warehouse/orders">
<span class="oi oi-people" aria-hidden="true"></span> Ordrer
<span class="oi oi-box" aria-hidden="true"></span> Forsendelse
</NavLink>
</div>
</AuthorizeView>

View file

@ -1,13 +1,13 @@
{
"appInfo": {
"name": "Wonky Client",
"version": "0.10.16",
"rc": false,
"version": "0.10.27",
"rc": true,
"sandBox": false,
"image": "grumpy-coder.png"
},
"apiConfig": {
"innoBaseUrl": "https://dev.innotec.dk",
"innoBaseUrl": "https://production.innotec.dk",
"glsTrackUrl": "https://www.gls-group.eu/276-I-PORTAL-WEB/content/GLS/DK01/DA/5004.htm?txtAction=71000&txtRefNo=",
"glsId": "",
"serviceVirk": "api/v2/services/virk",

View file

@ -17,7 +17,7 @@ using System.ComponentModel.DataAnnotations;
namespace Wonky.Entity.DTO;
public class AdminUserInfoDto
public class UserInfoDto
{
/// <summary>
/// First name