WIP: intermediate production release v.0.116.1
This commit is contained in:
parent
0ac35a1f10
commit
c461d4e26c
33 changed files with 224 additions and 383 deletions
|
@ -58,10 +58,10 @@
|
|||
<button class="btn btn-warning" @onclick="() => ShowActivityList(company.CompanyId)" >Aktivitet</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button class="btn btn-success" @onclick="() => ShowProductList(company.CompanyId)">Produkt</button>
|
||||
<button class="btn btn-success" @onclick="() => ShowInventory(company.CompanyId)">Produkt</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button class="btn btn-primary" disabled >Bestilling</button>
|
||||
@* <a class="btn btn-primary" href="/office/customers/@company.CountryCode.ToLower()/@company.CompanyId/order" >Bestilling</a> *@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -69,13 +69,13 @@
|
|||
</div>
|
||||
}
|
||||
</div>
|
||||
<OfficeCustomerInvoiceListOverlay Company="@SelectedCompany" InvoiceList="@InvoiceList" @ref="InvoiceListOverlay" />
|
||||
<OfficeCustomerActivityListOverlay Company="SelectedCompany" ActivityList="ActivityList" @ref="ActivityListOverlay" />
|
||||
<OfficeCustomerProductListOverlay Company="SelectedCompany" ProductList="ProductList" @ref="ProductListOverlay" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<div>Ingen data</div>
|
||||
}
|
||||
|
||||
<OfficeCustomerInvoiceListOverlay Company="@SelectedCompany" CustomerInvoices="@InvoiceViewList" @ref="InvoiceListOverlay" />
|
||||
<OfficeCustomerActivityListOverlay Activities="ActivityList" Company="SelectedCompany" @ref="ActivityListOverlay" />
|
||||
<OfficeCustomerProductListOverlay Company="SelectedCompany" ProductList="ProductList" @ref="ProductListOverlay" />
|
||||
|
||||
|
|
|
@ -13,68 +13,91 @@
|
|||
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||
//
|
||||
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.VisualBasic.CompilerServices;
|
||||
using Wonky.Client.HttpInterfaces;
|
||||
using Wonky.Client.OverlayOffice;
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Views;
|
||||
using Wonky.Client.Helpers;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Client.Shared;
|
||||
using Utils = Wonky.Client.Helpers.Utils;
|
||||
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace Wonky.Client.Components
|
||||
{
|
||||
public partial class OfficeCountryCustomerListComponent
|
||||
{
|
||||
[Parameter] public List<CompanyDto> CompanyList { get; set; } = new();
|
||||
// ******************************************************
|
||||
// parameters
|
||||
[Parameter] public string CountryCode { get; set; } = "";
|
||||
|
||||
[Parameter] public List<CompanyDto> CompanyList { get; set; } = new();
|
||||
// [Parameter] public EventCallback<DraftItem> OnOrderItem { get; set; }
|
||||
[CascadingParameter] public DraftStateProvider DraftProvider { get; set; }
|
||||
|
||||
// ******************************************************
|
||||
// injects
|
||||
[Inject] public ICountryCustomerHistoryRepository HistoryRepo { get; set; }
|
||||
[Inject] public ICountryActivityRepository ActivityRepo { get; set; }
|
||||
|
||||
|
||||
// ******************************************************
|
||||
// overlays
|
||||
private OfficeCustomerInvoiceListOverlay InvoiceListOverlay { get; set; } = new();
|
||||
private OfficeCustomerActivityListOverlay ActivityListOverlay { get; set; } = new();
|
||||
private OfficeCustomerProductListOverlay ProductListOverlay { get; set; } = new();
|
||||
|
||||
private string CompanyName { get; set; } = "";
|
||||
private string CompanyId { get; set; } = "";
|
||||
private string LastSync { get; set; } = "";
|
||||
|
||||
private InvoiceListView InvoiceViewList { get; set; } = new();
|
||||
|
||||
// ******************************************************
|
||||
// variables
|
||||
private InvoiceListView InvoiceList { get; set; } = new();
|
||||
private List<ReportItemView> ActivityList { get; set; } = new();
|
||||
private List<ProductInventoryView> ProductList { get; set; } = new();
|
||||
private CompanyDto SelectedCompany { get; set; } = new();
|
||||
|
||||
private void OnInventoryCallback()
|
||||
{
|
||||
}
|
||||
|
||||
// ******************************************************
|
||||
// functions
|
||||
private async Task ShowInvoiceList(string companyId)
|
||||
{
|
||||
// check for console manipulation
|
||||
if (!Utils.Validate(VType.Id, companyId)) return;
|
||||
SelectedCompany = CompanyList.First(x => x.CompanyId == companyId);
|
||||
// call erp to crm sync before requesting invoices
|
||||
// get company last sync from company list
|
||||
SelectedCompany = CompanyList.Find(x => x.CompanyId == companyId);
|
||||
var newSyncDate = await HistoryRepo.InvoiceErpToCrmRpc(CountryCode, companyId, SelectedCompany.HistorySync);
|
||||
var newSyncDate = await HistoryRepo.RequestErpToCrmSync(CountryCode, companyId, SelectedCompany.HistorySync);
|
||||
await Task.Delay(500);
|
||||
InvoiceViewList = await HistoryRepo.FetchInvoiceList(CountryCode, companyId);
|
||||
SelectedCompany.HistorySync = newSyncDate;
|
||||
InvoiceList = await HistoryRepo.RequestInvoiceList(CountryCode, companyId);
|
||||
if(!string.IsNullOrWhiteSpace(newSyncDate)) SelectedCompany.HistorySync = newSyncDate;
|
||||
InvoiceListOverlay.Show();
|
||||
}
|
||||
|
||||
private async Task ShowActivityList(string companyId)
|
||||
{
|
||||
// call erp to crm sync before requesting invoices
|
||||
// get company last sync from company list
|
||||
SelectedCompany = CompanyList.Find(x => x.CompanyId == companyId);
|
||||
ActivityList = await ActivityRepo.GetCustomerActivities(companyId);
|
||||
// check for console manipulation
|
||||
if (!Utils.Validate(VType.Id, companyId)) return;
|
||||
SelectedCompany = CompanyList.First(x => x.CompanyId == companyId);
|
||||
ActivityList = await ActivityRepo.RequestActitivityList(companyId);
|
||||
ActivityListOverlay.Show();
|
||||
}
|
||||
|
||||
private async Task ShowProductList(string companyId)
|
||||
private async Task ShowInventory(string companyId)
|
||||
{
|
||||
// call erp to crm sync before requesting invoices
|
||||
// get company last sync from company list
|
||||
SelectedCompany = CompanyList.Find(x => x.CompanyId == companyId);
|
||||
ProductList = await HistoryRepo.FetchInventory(SelectedCompany.CountryCode, SelectedCompany.CompanyId);
|
||||
// check for console manipulation
|
||||
if (!Utils.Validate(VType.Id, companyId)) return;
|
||||
SelectedCompany = CompanyList.First(x => x.CompanyId == companyId);
|
||||
// call erp to crm sync before requesting products
|
||||
var newSyncDate = await HistoryRepo.RequestErpToCrmSync(CountryCode, companyId, SelectedCompany.HistorySync);
|
||||
await Task.Delay(500);
|
||||
if(!string.IsNullOrWhiteSpace(newSyncDate)) SelectedCompany.HistorySync = newSyncDate;
|
||||
ProductList = await HistoryRepo.RequestInventory(SelectedCompany.CountryCode, SelectedCompany.CompanyId);
|
||||
ProductListOverlay.Show();
|
||||
}
|
||||
|
||||
private async Task ShowOrder(string companyId)
|
||||
{
|
||||
// check for console manipulation
|
||||
if (!Utils.Validate(VType.Id, companyId)) return;
|
||||
SelectedCompany = CompanyList.First(x => x.CompanyId == companyId);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,82 +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.Models
|
||||
@using System.ComponentModel.Design
|
||||
<div class="row">
|
||||
|
||||
@if (Inventory.Any())
|
||||
{
|
||||
<div class="list-group mt-2">
|
||||
<div class="list-group-item bg-dark text-white">
|
||||
<div class="row">
|
||||
<div class="col-sm-4" style="cursor: pointer;" @onclick="() => SortProducts(PSort.Desc)"><i class="bi-sort-alpha-down"></i> Navn <i class="bi-sort-alpha-up-alt"></i></div>
|
||||
<div class="col-sm-3" style="cursor: pointer;" @onclick="() => SortProducts(PSort.Sku)"><i class="bi-sort-alpha-down"></i> Varenr <i class="bi-sort-alpha-up-alt"></i></div>
|
||||
<div class="col-sm-2 text-center" style="cursor: pointer;" @onclick="() => SortProducts(PSort.Qty)"><i class="bi-sort-numeric-down"></i> Antal <i class="bi-sort-numeric-up-alt"></i></div>
|
||||
<div class="col-sm-2"></div>
|
||||
<div class="col-sm-1"></div>
|
||||
</div>
|
||||
</div>
|
||||
@foreach (var product in Inventory)
|
||||
{
|
||||
<div class="list-group-item">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-sm-4">
|
||||
<div class="position-relative">
|
||||
@product.Description
|
||||
@if (product.Discontinued)
|
||||
{
|
||||
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">Udgået</span>
|
||||
<span class="visually-hidden">Produktet er udgået</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
@product.Sku
|
||||
</div>
|
||||
<div class="col-sm-2 text-center">
|
||||
@product.Quantity
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<a class="btn btn-info d-block" type="button" @onclick="() => CallShowReorderModal(product.Sku)"><i class="bi-cart"></i> Genbestil</a>
|
||||
</div>
|
||||
<div class="col-sm-1" @onclick="() => ProductCheck(product.Sku)">
|
||||
<input type="checkbox" class="btn-check" id="btn-@product.Sku.Replace(",", "")" autocomplete="off"/>
|
||||
@if (product.Check)
|
||||
{
|
||||
<label class="btn btn-success" for="btn-@product.Sku.Replace(",", "")">
|
||||
<i class="bi-check"></i>
|
||||
</label>
|
||||
}
|
||||
else
|
||||
{
|
||||
<label class="btn btn-warning" for="btn-@product.Sku.Replace(",", "")">
|
||||
<i class="bi-dash"></i>
|
||||
</label>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div>Ingen data</div>
|
||||
}
|
||||
</div>
|
|
@ -1,86 +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 Blazored.LocalStorage;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Entity.Views;
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace Wonky.Client.Components;
|
||||
|
||||
public partial class OfficeCustomerInventoryListComponent
|
||||
{
|
||||
[Inject] private ILocalStorageService Storage { get; set; }
|
||||
// Parameters
|
||||
[Parameter] public List<ProductInventoryView> Inventory { get; set; } = new();
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
[Parameter] public EventCallback<string> OnReorderSelected { get; set; }
|
||||
|
||||
// private variables
|
||||
private bool Descending { get; set; }
|
||||
|
||||
private void SortProducts(PSort column)
|
||||
{
|
||||
Descending = !Descending;
|
||||
switch (column)
|
||||
{
|
||||
case PSort.Desc:
|
||||
if (Descending)
|
||||
{
|
||||
Inventory = Inventory.OrderByDescending(x => x.Description).ToList();
|
||||
break;
|
||||
}
|
||||
Inventory = Inventory.OrderBy(x => x.Description).ToList();
|
||||
break;
|
||||
case PSort.Sku:
|
||||
if (Descending)
|
||||
{
|
||||
Inventory = Inventory.OrderByDescending(x => x.Sku).ToList();
|
||||
break;
|
||||
}
|
||||
Inventory = Inventory.OrderBy(x => x.Sku).ToList();
|
||||
break;
|
||||
case PSort.Qty:
|
||||
if (Descending)
|
||||
{
|
||||
Inventory = Inventory.OrderByDescending(x => x.Quantity).ToList();
|
||||
break;
|
||||
}
|
||||
Inventory = Inventory.OrderBy(x => x.Quantity).ToList();
|
||||
break;
|
||||
case PSort.None:
|
||||
break;
|
||||
case PSort.Abbr:
|
||||
break;
|
||||
default:
|
||||
Inventory = Inventory.OrderByDescending(x => x.Quantity).ToList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CallShowReorderModal(string sku)
|
||||
{
|
||||
await ProductCheck(sku);
|
||||
await OnReorderSelected.InvokeAsync(sku);
|
||||
}
|
||||
|
||||
private async Task ProductCheck(string sku)
|
||||
{
|
||||
var x = Inventory.First(x => x.Sku == sku);
|
||||
x.Check = !x.Check;
|
||||
await Storage.SetItemAsync($"{CompanyId}-products", Inventory);
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
//
|
||||
|
||||
using System.Net.Mail;
|
||||
using Wonky.Client.Models;
|
||||
|
||||
namespace Wonky.Client.Helpers;
|
||||
|
||||
|
@ -22,12 +23,25 @@ namespace Wonky.Client.Helpers;
|
|||
/// </summary>
|
||||
public static class Utils
|
||||
{
|
||||
public static bool Validate(VType vType, string toValidate)
|
||||
{
|
||||
return vType switch
|
||||
{
|
||||
VType.ISODate => toValidate.Length == 10 && DateTime.TryParse(toValidate, out _),
|
||||
VType.Id => Squid.TryDecode(toValidate, out _),
|
||||
VType.Passwd => IsValidPasswd(toValidate),
|
||||
VType.Email => IsValidEmail(toValidate),
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// validate password to contain a-z and A-Z and 0-9
|
||||
/// </summary>
|
||||
/// <param name="toValidate"></param>
|
||||
/// <param name="length">optional (default 10)</param>
|
||||
/// <returns></returns>
|
||||
public static bool ValidatePasswd(string toValidate, int length)
|
||||
public static bool IsValidPasswd(string toValidate, int length = 10)
|
||||
{
|
||||
if (toValidate.Length < length)
|
||||
return false;
|
||||
|
|
|
@ -36,5 +36,5 @@ public interface ICountryActivityRepository
|
|||
/// </summary>
|
||||
/// <param name="customerId"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<ReportItemView>> GetCustomerActivities(string customerId);
|
||||
Task<List<ReportItemView>> RequestActitivityList(string customerId);
|
||||
}
|
|
@ -28,7 +28,7 @@ public interface ICountryCustomerHistoryRepository
|
|||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <returns></returns>
|
||||
Task<InvoiceListView> FetchInvoiceList(string countryCode, string companyId);
|
||||
Task<InvoiceListView> RequestInvoiceList(string countryCode, string companyId);
|
||||
|
||||
/// <summary>
|
||||
/// Fetch given invoice for given customer
|
||||
|
@ -43,7 +43,7 @@ public interface ICountryCustomerHistoryRepository
|
|||
/// </summary>
|
||||
/// <param name="companyId"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<ProductInventoryView>> FetchInventory(string countryCode, string companyId);
|
||||
Task<List<ProductInventoryView>> RequestInventory(string countryCode, string companyId);
|
||||
|
||||
/// <summary>
|
||||
/// Fetch History for given customer
|
||||
|
@ -58,7 +58,7 @@ public interface ICountryCustomerHistoryRepository
|
|||
/// <param name="companyId"></param>
|
||||
/// <param name="sku"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<ProductHistoryView>> FetchHistory(string countryCode, string companyId, string sku);
|
||||
Task<List<ProductHistoryView>> FetchHistorySku(string countryCode, string companyId, string sku);
|
||||
|
||||
/// <summary>
|
||||
/// RPC call to initiate remote server sync for given customer
|
||||
|
@ -66,5 +66,5 @@ public interface ICountryCustomerHistoryRepository
|
|||
/// <param name="companyId"></param>
|
||||
/// <param name="syncDate"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> InvoiceErpToCrmRpc(string countryCode, string companyId, string syncDate);
|
||||
Task<string> RequestErpToCrmSync(string countryCode, string companyId, string syncDate);
|
||||
}
|
|
@ -67,7 +67,7 @@ public class CountryActivityRepository : ICountryActivityRepository
|
|||
/// </summary>
|
||||
/// <param name="customerId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<ReportItemView>> GetCustomerActivities(string customerId)
|
||||
public async Task<List<ReportItemView>> RequestActitivityList(string customerId)
|
||||
{
|
||||
var response = await _client.GetAsync($"{_api.CrmActivities}/company/{customerId}");
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
|
|
|
@ -52,7 +52,7 @@ public class CountryCustomerHistoryRepository : ICountryCustomerHistoryRepositor
|
|||
/// <param name="countryCode"></param>
|
||||
/// <param name="companyId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<InvoiceListView> FetchInvoiceList(string countryCode, string companyId)
|
||||
public async Task<InvoiceListView> RequestInvoiceList(string countryCode, string companyId)
|
||||
{
|
||||
var response = await _client.GetAsync($"{_api.OfficeCustomers}/{countryCode}/{companyId}/invoices");
|
||||
|
||||
|
@ -89,7 +89,7 @@ public class CountryCustomerHistoryRepository : ICountryCustomerHistoryRepositor
|
|||
/// <param name="countryCode"></param>
|
||||
/// <param name="companyId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<ProductInventoryView>> FetchInventory(string countryCode, string companyId)
|
||||
public async Task<List<ProductInventoryView>> RequestInventory(string countryCode, string companyId)
|
||||
{
|
||||
var response = await _client.GetAsync($"{_api.OfficeCustomers}/{countryCode}/{companyId}/history/inventory");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
|
@ -125,7 +125,7 @@ public class CountryCustomerHistoryRepository : ICountryCustomerHistoryRepositor
|
|||
/// <param name="companyId"></param>
|
||||
/// <param name="sku"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<ProductHistoryView>> FetchHistory(string countryCode, string companyId, string sku)
|
||||
public async Task<List<ProductHistoryView>> FetchHistorySku(string countryCode, string companyId, string sku)
|
||||
{
|
||||
var response = await _client.GetAsync($"{_api.OfficeCustomers}/{countryCode}/{companyId}/history/products/{sku}");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
|
@ -143,7 +143,7 @@ public class CountryCustomerHistoryRepository : ICountryCustomerHistoryRepositor
|
|||
/// <param name="companyId"></param>
|
||||
/// <param name="syncDate"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> InvoiceErpToCrmRpc(string countryCode, string companyId, string syncDate)
|
||||
public async Task<string> RequestErpToCrmSync(string countryCode, string companyId, string syncDate)
|
||||
{
|
||||
var x = await _client.GetAsync($"{_api.OfficeCustomers}/{countryCode}/{companyId}/{_api.SyncRpcInvoiceExt}/{syncDate}");
|
||||
if (!x.IsSuccessStatusCode)
|
||||
|
|
9
Wonky.Client/Models/VType.cs
Normal file
9
Wonky.Client/Models/VType.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace Wonky.Client.Models;
|
||||
|
||||
public enum VType
|
||||
{
|
||||
Id,
|
||||
ISODate,
|
||||
Passwd,
|
||||
Email
|
||||
}
|
|
@ -25,7 +25,7 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
@* activity list *@
|
||||
<OfficeCustomerActivityListComponent Activities="Activities"/>
|
||||
<OfficeCustomerActivityListComponent Activities="ActivityList"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace Wonky.Client.OverlayOffice;
|
|||
public partial class OfficeCustomerActivityListOverlay
|
||||
{
|
||||
[Parameter] public CompanyDto Company { get; set; } = new();
|
||||
[Parameter] public List<ReportItemView> Activities { get; set; } = new();
|
||||
[Parameter] public List<ReportItemView> ActivityList { get; set; } = new();
|
||||
|
||||
private string _modalDisplay = "";
|
||||
private bool _showBackdrop;
|
||||
|
|
|
@ -1,38 +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
|
||||
|
||||
<div class="modal" tabindex="-1" role="dialog" style="display:@_modalDisplay">
|
||||
<div class="modal-dialog modal-dialog-scrollable modal-fullscreen">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">@CompanyName - Produktoversigt</h3>
|
||||
<button type="button" class="btn-close" @onclick="Hide" data-bs-dismiss="modal" aria-label="Luk"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@* product list *@
|
||||
<OfficeCustomerInventoryListComponent OnReorderSelected="OnReorderCallback" CompanyId="@CompanyId" Inventory="@Inventory"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (_showBackdrop)
|
||||
{
|
||||
<div class="modal-backdrop fade show"></div>
|
||||
}
|
||||
@* reorder overlay *@
|
||||
<OfficeCustomerInventoryReorderOverlay CompanyId="@CompanyId" SalesItem="SalesItem" OnSelected="OnInventorySelected" @ref="ReorderOverlay" />
|
|
@ -1,85 +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.Client.HttpInterceptors;
|
||||
using Wonky.Client.HttpInterfaces;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Views;
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace Wonky.Client.OverlayOffice;
|
||||
|
||||
public partial class OfficeCustomerInventoryListOverlay : IDisposable
|
||||
{
|
||||
[Inject] private HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] private ICountryCatalogRepository CatalogRepo { get; set; }
|
||||
[Inject] private ILogger<OfficeCustomerInventoryListOverlay> Logger { get; set; }
|
||||
|
||||
|
||||
[Parameter] public string CompanyName { get; set; } = "";
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
[Parameter] public string CountryCode { get; set; } = "";
|
||||
[Parameter] public List<ProductInventoryView> Inventory { get; set; } = new();
|
||||
[Parameter] public EventCallback<DraftItem> OnInventorySelected { get; set; }
|
||||
|
||||
|
||||
private string _modalDisplay = "";
|
||||
private bool _showBackdrop;
|
||||
private CompanyDto _company { get; set; } = new();
|
||||
private List<ProductInventoryView> _inventory { get; set; } = new();
|
||||
private DraftItem DraftItem { get; set; } = new();
|
||||
private SalesItemView SalesItem { get; set; } = new();
|
||||
private OfficeCustomerInventoryReorderOverlay ReorderOverlay { get; set; } = new();
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Interceptor.RegisterEvent();
|
||||
Interceptor.RegisterBeforeSendEvent();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task OnReorderCallback(string sku)
|
||||
{
|
||||
SalesItem = await CatalogRepo.GetSalesItemSku(CountryCode.ToLower(), sku);
|
||||
ReorderOverlay.Show();
|
||||
}
|
||||
|
||||
private async Task OnSelectedItem(DraftItem draftItem)
|
||||
{
|
||||
await OnInventorySelected.InvokeAsync(draftItem);
|
||||
Hide();
|
||||
}
|
||||
|
||||
public void Show()
|
||||
{
|
||||
_modalDisplay = "block;";
|
||||
_showBackdrop = true;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void Hide()
|
||||
{
|
||||
_modalDisplay = "none;";
|
||||
_showBackdrop = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Interceptor.DisposeEvent();
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ using System.Globalization;
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Wonky.Client.HttpInterfaces;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Views;
|
||||
#pragma warning disable CS8618
|
||||
|
||||
|
@ -25,11 +26,11 @@ namespace Wonky.Client.OverlayOffice;
|
|||
|
||||
public partial class OfficeCustomerInventoryReorderOverlay
|
||||
{
|
||||
[Parameter] public string CompanyId { get; set; } = "";
|
||||
[Parameter] public CompanyDto Company { get; set; }
|
||||
[Parameter] public SalesItemView SalesItem { get; set; } = new();
|
||||
[Inject] public ICountryCustomerHistoryRepository HistoryRepo { get; set; }
|
||||
[Parameter] public EventCallback<DraftItem> OnSelected { get; set; }
|
||||
private List<ProductHistoryView>? History { get; set; } = new();
|
||||
[Parameter] public EventCallback<DraftItem> OrderItemCallback { get; set; }
|
||||
private List<ProductHistoryView> History { get; set; } = new();
|
||||
private DraftItem SelectedItem { get; set; } = new();
|
||||
private string ProductName { get; set; } = "";
|
||||
private string _modalDisplay = "";
|
||||
|
@ -41,9 +42,9 @@ public partial class OfficeCustomerInventoryReorderOverlay
|
|||
if (string.IsNullOrWhiteSpace(SalesItem.Sku))
|
||||
return;
|
||||
|
||||
History = await HistoryRepo.FetchHistory(CompanyId, SalesItem.Sku);
|
||||
if (!History.Any())
|
||||
await Task.Delay(1000);
|
||||
History = await HistoryRepo.FetchHistorySku(Company.CountryCode, Company.CompanyId, SalesItem.Sku);
|
||||
// if (!History.Any())
|
||||
// await Task.Delay(500);
|
||||
SelectedItem.Item = SalesItem;
|
||||
SelectedItem.Discount = 0;
|
||||
SelectedItem.Quantity = 1;
|
||||
|
@ -54,7 +55,7 @@ public partial class OfficeCustomerInventoryReorderOverlay
|
|||
private async Task SendToOrder(DraftItem item)
|
||||
{
|
||||
SelectedItem = new DraftItem();
|
||||
await OnSelected.InvokeAsync(item);
|
||||
await OrderItemCallback.InvokeAsync(item);
|
||||
Hide();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace Wonky.Client.OverlayOffice;
|
|||
|
||||
public partial class OfficeCustomerInvoiceListOverlay
|
||||
{
|
||||
[Parameter] public InvoiceListView CustomerInvoices { get; set; } = new();
|
||||
[Parameter] public InvoiceListView InvoiceList { get; set; } = new();
|
||||
[Parameter] public CompanyDto Company { get; set; } = new();
|
||||
// dependency injection
|
||||
[Inject] private ILogger<OfficeCustomerInvoiceListOverlay> Logger { get; set; }
|
||||
|
@ -39,8 +39,8 @@ public partial class OfficeCustomerInvoiceListOverlay
|
|||
// extract company from customer invoices
|
||||
Logger.LogDebug("CustomerInvoiceListOverlay => company => {}", JsonSerializer.Serialize(Company));
|
||||
// if there is invoices -> order by document date
|
||||
if (CustomerInvoices.Invoices.Any())
|
||||
Invoices = CustomerInvoices.Invoices.OrderByDescending(x => x.DocumentDate).ToList();
|
||||
if (InvoiceList.Invoices.Any())
|
||||
Invoices = InvoiceList.Invoices.OrderByDescending(x => x.DocumentDate).ToList();
|
||||
Logger.LogDebug("invoices => {}", JsonSerializer.Serialize(Invoices));
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
|
||||
//
|
||||
*@
|
||||
@using Wonky.Client.Components
|
||||
@using Wonky.Client.Models
|
||||
|
||||
<div class="modal" tabindex="-1" role="dialog" style="display:@_modalDisplay">
|
||||
<div class="modal-dialog modal-dialog-scrollable modal-fullscreen">
|
||||
|
@ -24,8 +24,51 @@
|
|||
<button type="button" class="btn-close" @onclick="Hide" data-bs-dismiss="modal" aria-label="Luk"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@* product list *@
|
||||
<CustomerInventoryListComponent OnReorderSelected="OnReorderCallback" CompanyId="@Company.CompanyId" Inventory="@ProductList"/>
|
||||
<div class="row">
|
||||
@if (ProductList.Any())
|
||||
{
|
||||
<div class="list-group mt-2">
|
||||
<div class="list-group-item bg-dark text-white">
|
||||
<div class="row">
|
||||
<div class="col-sm-4" style="cursor: pointer;" @onclick="() => SortProducts(PSort.Desc)"><i class="bi-sort-alpha-down"></i> Navn <i class="bi-sort-alpha-up-alt"></i></div>
|
||||
<div class="col-sm-3" style="cursor: pointer;" @onclick="() => SortProducts(PSort.Sku)"><i class="bi-sort-alpha-down"></i> Varenr <i class="bi-sort-alpha-up-alt"></i></div>
|
||||
<div class="col-sm-2 text-center" style="cursor: pointer;" @onclick="() => SortProducts(PSort.Qty)"><i class="bi-sort-numeric-down"></i> Antal <i class="bi-sort-numeric-up-alt"></i></div>
|
||||
<div class="col-sm-2"></div>
|
||||
<div class="col-sm-1"></div>
|
||||
</div>
|
||||
</div>
|
||||
@foreach (var product in ProductList)
|
||||
{
|
||||
<div class="list-group-item">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-sm-4">
|
||||
<div class="position-relative">
|
||||
@product.Description
|
||||
@if (product.Discontinued)
|
||||
{
|
||||
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">Udgået</span>
|
||||
<span class="visually-hidden">Produktet er udgået</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
@product.Sku
|
||||
</div>
|
||||
<div class="col-sm-2 text-center">
|
||||
@product.Quantity
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div>Ingen data</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -34,5 +77,9 @@
|
|||
{
|
||||
<div class="modal-backdrop fade show"></div>
|
||||
}
|
||||
@* reorder overlay *@
|
||||
<OfficeCustomerInventoryReorderOverlay CompanyId="@Company.CompanyId" SalesItem="SalesItem" OnSelected="OnInventorySelected" @ref="ReorderOverlay" />
|
||||
@*
|
||||
reorder overlay
|
||||
invoked by list component OnReorderSku=OnReorderCallback
|
||||
*@
|
||||
|
||||
<OfficeCustomerInventoryReorderOverlay Company="Company" SalesItem="SalesItem" @ref="ReorderOverlay"/>
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
// 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
|
||||
|
@ -20,6 +19,7 @@ using Wonky.Client.HttpInterfaces;
|
|||
using Wonky.Client.Models;
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace Wonky.Client.OverlayOffice;
|
||||
|
@ -29,52 +29,85 @@ public partial class OfficeCustomerProductListOverlay : IDisposable
|
|||
[Inject] private HttpInterceptorService Interceptor { get; set; }
|
||||
[Inject] private ICountryCatalogRepository CatalogRepo { get; set; }
|
||||
[Inject] private ILogger<OfficeCustomerProductListOverlay> Logger { get; set; }
|
||||
|
||||
[Parameter] public CompanyDto Company { get; set; }
|
||||
[Parameter] public List<ProductInventoryView> ProductList { get; set; } = new();
|
||||
[Parameter] public EventCallback<DraftItem> OnInventorySelected { get; set; }
|
||||
|
||||
|
||||
private string _modalDisplay = "";
|
||||
private bool _showBackdrop;
|
||||
private CompanyDto _company { get; set; } = new();
|
||||
private List<ProductInventoryView> _inventory { get; set; } = new();
|
||||
private DraftItem DraftItem { get; set; } = new();
|
||||
private SalesItemView SalesItem { get; set; } = new();
|
||||
private OfficeCustomerInventoryReorderOverlay ReorderOverlay { get; set; } = new();
|
||||
private bool Descending { get; set; }
|
||||
|
||||
[Parameter] public CompanyDto Company { get; set; } = new();
|
||||
[Parameter] public List<ProductInventoryView> ProductList { get; set; } = new();
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Interceptor.RegisterEvent();
|
||||
Interceptor.RegisterBeforeSendEvent();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task OnReorderCallback(string sku)
|
||||
|
||||
private async Task ShowSkuReorder(string sku)
|
||||
{
|
||||
SalesItem = await CatalogRepo.GetSalesItemSku(Company.CountryCode.ToLower(), sku);
|
||||
ReorderOverlay.Show();
|
||||
}
|
||||
|
||||
private async Task OnSelectedItem(DraftItem draftItem)
|
||||
{
|
||||
await OnInventorySelected.InvokeAsync(draftItem);
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void SortProducts(PSort column)
|
||||
{
|
||||
Descending = !Descending;
|
||||
switch (column)
|
||||
{
|
||||
case PSort.Desc:
|
||||
if (Descending)
|
||||
{
|
||||
ProductList = ProductList.OrderByDescending(x => x.Description).ToList();
|
||||
break;
|
||||
}
|
||||
|
||||
ProductList = ProductList.OrderBy(x => x.Description).ToList();
|
||||
break;
|
||||
case PSort.Sku:
|
||||
if (Descending)
|
||||
{
|
||||
ProductList = ProductList.OrderByDescending(x => x.Sku).ToList();
|
||||
break;
|
||||
}
|
||||
|
||||
ProductList = ProductList.OrderBy(x => x.Sku).ToList();
|
||||
break;
|
||||
case PSort.Qty:
|
||||
if (Descending)
|
||||
{
|
||||
ProductList = ProductList.OrderByDescending(x => x.Quantity).ToList();
|
||||
break;
|
||||
}
|
||||
|
||||
ProductList = ProductList.OrderBy(x => x.Quantity).ToList();
|
||||
break;
|
||||
case PSort.None:
|
||||
break;
|
||||
case PSort.Abbr:
|
||||
break;
|
||||
default:
|
||||
ProductList = ProductList.OrderByDescending(x => x.Quantity).ToList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
public void Show()
|
||||
{
|
||||
_modalDisplay = "block;";
|
||||
_showBackdrop = true;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
private void Hide()
|
||||
{
|
||||
_modalDisplay = "none;";
|
||||
_showBackdrop = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Interceptor.DisposeEvent();
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Wonky.Client.HttpInterceptors;
|
||||
using Wonky.Client.HttpInterfaces;
|
||||
using Wonky.Client.HttpRepository;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Client.Services;
|
||||
using Wonky.Entity.Requests;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace Wonky.Client.Shared;
|
||||
namespace Wonky.Client.OverlayOrderCreate;
|
||||
|
||||
public partial class PriceCatalogOverlay : IDisposable
|
||||
{
|
|
@ -17,7 +17,7 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
namespace Wonky.Client.Shared;
|
||||
namespace Wonky.Client.OverlayOrderCreate;
|
||||
|
||||
public partial class ProductCheckConfirmationOverlay
|
||||
{
|
|
@ -15,16 +15,12 @@
|
|||
//
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Wonky.Client.HttpInterceptors;
|
||||
using Wonky.Client.HttpInterfaces;
|
||||
using Wonky.Client.HttpRepository;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Client.Services;
|
||||
using Wonky.Entity.Requests;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace Wonky.Client.Shared;
|
||||
namespace Wonky.Client.OverlayOrderCreate;
|
||||
|
||||
public partial class ProductHistoryOverlay
|
||||
{
|
|
@ -17,9 +17,10 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Wonky.Client.HttpInterfaces;
|
||||
using Wonky.Entity.Views;
|
||||
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace Wonky.Client.Shared;
|
||||
namespace Wonky.Client.OverlayOrderCreate;
|
||||
|
||||
public partial class ProductPriceHistoryOverlay
|
||||
{
|
|
@ -18,6 +18,7 @@
|
|||
@using Microsoft.AspNetCore.Authorization
|
||||
@using Wonky.Client.Components
|
||||
@using Wonky.Client.OverlayCustomer
|
||||
@using Wonky.Client.OverlayOrderCreate
|
||||
@attribute [Authorize(Roles = "Advisor")]
|
||||
@page "/advisor/customers/{CompanyId}/activities/new"
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ using Wonky.Client.HttpInterceptors;
|
|||
using Wonky.Client.HttpInterfaces;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Client.OverlayCustomer;
|
||||
using Wonky.Client.OverlayOrderCreate;
|
||||
using Wonky.Client.Services;
|
||||
using Wonky.Client.Shared;
|
||||
using Wonky.Entity.DTO;
|
||||
|
|
|
@ -16,8 +16,9 @@
|
|||
*@
|
||||
|
||||
@using Wonky.Client.Components
|
||||
@using Wonky.Client.OverlayOrderCreate
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@attribute [Authorize(Roles = "Admin,Office,Warehouse")]
|
||||
@attribute [Authorize(Roles = "Admin,Office,Supervisor,Warehouse")]
|
||||
@page "/office/customers/{CountryCode}/{CompanyId}/order"
|
||||
|
||||
<PageTitle>Telefon Ordre - @Customer.Name - @Customer.Account</PageTitle>
|
||||
|
|
|
@ -20,6 +20,7 @@ using Microsoft.AspNetCore.Components.Forms;
|
|||
using Wonky.Client.HttpInterceptors;
|
||||
using Wonky.Client.HttpInterfaces;
|
||||
using Wonky.Client.Models;
|
||||
using Wonky.Client.OverlayOrderCreate;
|
||||
using Wonky.Client.Shared;
|
||||
using Wonky.Entity.DTO;
|
||||
using Wonky.Entity.Views;
|
||||
|
|
|
@ -83,7 +83,7 @@ public partial class SystemUserViewEditPage : IDisposable
|
|||
private void PwValidationChanged(object sender, ValidationStateChangedEventArgs e)
|
||||
{
|
||||
PwInvalid = true;
|
||||
if (!Utils.ValidatePasswd(Passwords.NewPassword, MinPwLength))
|
||||
if (!Utils.IsValidPasswd(Passwords.NewPassword, MinPwLength))
|
||||
return;
|
||||
|
||||
PasswdContext.OnFieldChanged -= PwHandleFieldChanged;
|
||||
|
|
|
@ -3795,4 +3795,8 @@
|
|||
<None Remove="wwwroot\icons\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="OverlayAdvisor" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"appInfo": {
|
||||
"name": "Wonky Online",
|
||||
"version": "0.116.0",
|
||||
"version": "0.116.1",
|
||||
"rc": true,
|
||||
"sandBox": false,
|
||||
"image": "grumpy-coder.png"
|
||||
|
@ -19,7 +19,7 @@
|
|||
}
|
||||
},
|
||||
"apiConfig": {
|
||||
"baseUrl": "https://dev.innotec.dk",
|
||||
"baseUrl": "https://zeta.innotec.dk",
|
||||
"catalog": "api/v2/catalog/country",
|
||||
"crmCustomers": "api/v2/crm/companies",
|
||||
"crmInventoryExt": "history/inventory",
|
||||
|
|
Loading…
Reference in a new issue