WIP: office create order

This commit is contained in:
Frede Hundewadt 2023-02-22 13:09:58 +01:00
parent 0b55511b7e
commit b4819ce547
25 changed files with 722 additions and 252 deletions

View file

@ -31,7 +31,12 @@ public partial class CustomerInventoryListComponent
// private variables
private bool Descending { get; set; }
protected override void OnParametersSet()
{
if(Inventory.Any())
Inventory = Inventory.OrderBy(x => x.Description).ToList();
}
private void SortProducts(PSort column)
{
Descending = !Descending;
@ -62,11 +67,12 @@ public partial class CustomerInventoryListComponent
Inventory = Inventory.OrderBy(x => x.Quantity).ToList();
break;
case PSort.None:
Inventory = Inventory.OrderBy(x => x.Description).ToList();
break;
case PSort.Abbr:
break;
default:
Inventory = Inventory.OrderByDescending(x => x.Quantity).ToList();
Inventory = Inventory.OrderBy(x => x.Description).ToList();
break;
}
}

View file

@ -19,7 +19,7 @@
@using System.ComponentModel.Design
<div class="row">
@if (ProductList.Any())
@if (Inventory.Any())
{
<div class="list-group mt-2">
<div class="list-group-item">
@ -31,7 +31,7 @@
<div class="col-sm-1"></div>
</div>
</div>
@foreach (var product in ProductList)
@foreach (var product in Inventory)
{
<div class="list-group-item">
<div class="row align-items-center">

View file

@ -22,12 +22,18 @@ using Wonky.Entity.Views;
namespace Wonky.Client.Components;
public partial class CustomerProductCheckListComponent
{
[Parameter] public List<ProductInventoryView> ProductList { get; set; } = new();
[Parameter] public List<ProductInventoryView> Inventory { get; set; } = new();
[Parameter] public string CompanyId { get; set; } = "";
[Inject] public ILocalStorageService Storage { get; set; }
// private variables
private bool Descending { get; set; }
protected override void OnParametersSet()
{
if(Inventory.Any())
Inventory = Inventory.OrderBy(x => x.Description).ToList();
}
private void SortProducts(PSort column)
{
Descending = !Descending;
@ -36,41 +42,41 @@ public partial class CustomerProductCheckListComponent
case PSort.Desc:
if (Descending)
{
ProductList = ProductList.OrderByDescending(x => x.Description).ToList();
Inventory = Inventory.OrderByDescending(x => x.Description).ToList();
break;
}
ProductList = ProductList.OrderBy(x => x.Description).ToList();
Inventory = Inventory.OrderBy(x => x.Description).ToList();
break;
case PSort.Sku:
if (Descending)
{
ProductList = ProductList.OrderByDescending(x => x.Sku).ToList();
Inventory = Inventory.OrderByDescending(x => x.Sku).ToList();
break;
}
ProductList = ProductList.OrderBy(x => x.Sku).ToList();
Inventory = Inventory.OrderBy(x => x.Sku).ToList();
break;
case PSort.Qty:
if (Descending)
{
ProductList = ProductList.OrderByDescending(x => x.Quantity).ToList();
Inventory = Inventory.OrderByDescending(x => x.Quantity).ToList();
break;
}
ProductList = ProductList.OrderBy(x => x.Quantity).ToList();
Inventory = Inventory.OrderBy(x => x.Quantity).ToList();
break;
case PSort.None:
break;
case PSort.Abbr:
break;
default:
ProductList = ProductList.OrderByDescending(x => x.Quantity).ToList();
Inventory = Inventory.OrderByDescending(x => x.Quantity).ToList();
break;
}
}
private async Task ProductCheck(string sku)
{
var x = ProductList.First(x => x.Sku == sku);
var x = Inventory.First(x => x.Sku == sku);
x.Check = !x.Check;
await Storage.SetItemAsync($"{CompanyId}-products", ProductList);
await Storage.SetItemAsync($"{CompanyId}-products", Inventory);
}
}

View file

@ -15,7 +15,7 @@
//
*@
@if (ProductHistory.Any())
@if (Inventory.Any())
{
<table class="table table-striped">
<thead>
@ -41,7 +41,7 @@
</tr>
</thead>
<tbody>
@foreach (var line in ProductHistory)
@foreach (var line in Inventory)
{
<tr class="align-content-center">
<td>

View file

@ -20,6 +20,11 @@ namespace Wonky.Client.Components;
public partial class CustomerProductLineListComponent
{
[Parameter] public List<ProductHistoryView> ProductHistory { get; set; } = new();
[Parameter] public List<ProductHistoryView> Inventory { get; set; } = new();
protected override void OnParametersSet()
{
if(Inventory.Any())
Inventory = Inventory.OrderBy(x => x.Description).ToList();
}
}

View file

@ -71,7 +71,7 @@
</div>
<OfficeCustomerInvoiceListOverlay Company="@SelectedCompany" InvoiceList="@InvoiceList" @ref="InvoiceListOverlay" />
<OfficeCustomerActivityListOverlay Company="SelectedCompany" ActivityList="ActivityList" @ref="ActivityListOverlay" />
<OfficeCustomerProductListOverlay Company="SelectedCompany" ProductList="ProductList" @ref="ProductListOverlay" />
<OfficeCustomerProductListOverlay Company="SelectedCompany" Inventory="ProductList" @ref="ProductListOverlay" />
}
else
{

View file

@ -0,0 +1,67 @@
@*
// 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">
<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-3">
<a class="btn btn-info d-block" type="button" @onclick="() => CallShowReorderModal(product.Sku)"><i class="bi-cart"></i> Genbestil</a>
</div>
</div>
</div>
}
</div>
}
else
{
<div>Ingen data</div>
}
</div>

View file

@ -0,0 +1,88 @@
// 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;
namespace Wonky.Client.Components;
#pragma warning disable CS8618
public partial class OfficeInventoryListComponent
{
// *************************************************************
// Injections
[Inject] public 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; }
protected override void OnParametersSet()
{
if(Inventory.Any())
Inventory = Inventory.OrderBy(x => x.Description).ToList();
}
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);
}
}

View file

@ -40,11 +40,17 @@ public partial class CustomerInventoryListOverlay : IDisposable
private string _modalDisplay = "";
private bool _showBackdrop;
private CompanyDto Company { get; set; } = new();
private List<ProductInventoryView> ProductList { get; set; } = new();
// private List<ProductInventoryView> ProductList { get; set; } = new();
private DraftItem DraftItem { get; set; } = new();
private SalesItemView SalesItem { get; set; } = new();
private CustomerInventoryReorderOverlay ReorderOverlay { get; set; } = new();
protected override void OnParametersSet()
{
if(Inventory.Any())
Inventory = Inventory.OrderBy(x => x.Description).ToList();
}
protected override void OnInitialized()
{
Interceptor.RegisterEvent();

View file

@ -21,16 +21,13 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Faktura</h5>
@if (!string.IsNullOrWhiteSpace(Company.Name))
{
<h3 class="modal-title">@Company.Name - Faktura Oversigt</h3>
}
<button type="button" class="btn-close" @onclick="Hide" data-bs-dismiss="modal" aria-label="Luk"></button>
</div>
<div class="modal-body">
<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>
<CustomerInvoiceListComponent OnShowInvoice="@CallInvoiceModal" CompanyId="@Company.CompanyId" InvoiceList="@Invoices"/>
</div>
</div>

View file

@ -20,7 +20,10 @@
<div class="modal-dialog modal-dialog-scrollable modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Faktura</h5>
@if (!string.IsNullOrWhiteSpace(Invoice.Company.Name))
{
<h3 class="modal-title">Faktura @Invoice.DocumentNumber</h3>
}
<button type="button" class="btn-close" @onclick="Hide" data-bs-dismiss="modal" aria-label="Luk"></button>
</div>
<div class="modal-body">

View file

@ -25,7 +25,7 @@
</div>
<div class="modal-body">
<div class="row">
@if (ProductList.Any())
@if (Inventory.Any())
{
<div class="list-group mt-2">
<div class="list-group-item bg-dark text-white">
@ -37,7 +37,7 @@
<div class="col-sm-1"></div>
</div>
</div>
@foreach (var product in ProductList)
@foreach (var product in Inventory)
{
<div class="list-group-item">
<div class="row align-items-center">

View file

@ -38,8 +38,13 @@ public partial class OfficeCustomerProductListOverlay : IDisposable
private bool Descending { get; set; }
[Parameter] public CompanyDto Company { get; set; } = new();
[Parameter] public List<ProductInventoryView> ProductList { get; set; } = new();
[Parameter] public List<ProductInventoryView> Inventory { get; set; } = new();
protected override void OnParametersSet()
{
if(Inventory.Any())
Inventory = Inventory.OrderBy(x => x.Description).ToList();
}
protected override void OnInitialized()
{
Interceptor.RegisterEvent();
@ -61,36 +66,36 @@ public partial class OfficeCustomerProductListOverlay : IDisposable
case PSort.Desc:
if (Descending)
{
ProductList = ProductList.OrderByDescending(x => x.Description).ToList();
Inventory = Inventory.OrderByDescending(x => x.Description).ToList();
break;
}
ProductList = ProductList.OrderBy(x => x.Description).ToList();
Inventory = Inventory.OrderBy(x => x.Description).ToList();
break;
case PSort.Sku:
if (Descending)
{
ProductList = ProductList.OrderByDescending(x => x.Sku).ToList();
Inventory = Inventory.OrderByDescending(x => x.Sku).ToList();
break;
}
ProductList = ProductList.OrderBy(x => x.Sku).ToList();
Inventory = Inventory.OrderBy(x => x.Sku).ToList();
break;
case PSort.Qty:
if (Descending)
{
ProductList = ProductList.OrderByDescending(x => x.Quantity).ToList();
Inventory = Inventory.OrderByDescending(x => x.Quantity).ToList();
break;
}
ProductList = ProductList.OrderBy(x => x.Quantity).ToList();
Inventory = Inventory.OrderBy(x => x.Quantity).ToList();
break;
case PSort.None:
break;
case PSort.Abbr:
break;
default:
ProductList = ProductList.OrderByDescending(x => x.Quantity).ToList();
Inventory = Inventory.OrderByDescending(x => x.Quantity).ToList();
break;
}
}

View file

@ -0,0 +1,37 @@
@*
// 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">@Company.Name - Produktoversigt</h3>
<button type="button" class="btn-close" @onclick="Hide" data-bs-dismiss="modal" aria-label="Luk"></button>
</div>
<div class="modal-body">
<OfficeInventoryListComponent OnReorderSelected="OnReorderCallback" CompanyId="@Company.CompanyId" Inventory="@Inventory"/>
</div>
</div>
</div>
</div>
@if (_showBackdrop)
{
<div class="modal-backdrop fade show"></div>
}
<OfficeOrderInventoryReorderOverlay Company="@Company" SalesItem="SalesItem" OnSelected="OnSelected" @ref="ReorderOverlay" />

View file

@ -0,0 +1,88 @@
// 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.HttpRepository;
using Wonky.Client.Models;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
#pragma warning disable CS8618
namespace Wonky.Client.OverlayOffice;
public partial class OfficeOrderInventoryListOverlay : IDisposable
{
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public ICountryCatalogRepository CatalogRepo { get; set; }
[Inject] public ILogger<OfficeOrderInventoryListOverlay> Logger { get; set; }
[Parameter] public CompanyDto Company { get; set; } = new();
[Parameter] public List<ProductInventoryView> Inventory { get; set; } = new();
[Parameter] public EventCallback<DraftItem> OnSelected { get; set; }
private string _modalDisplay = "";
private bool _showBackdrop;
// private List<ProductInventoryView> ProductList { get; set; } = new();
private DraftItem DraftItem { get; set; } = new();
private SalesItemView SalesItem { get; set; } = new();
private OfficeOrderInventoryReorderOverlay ReorderOverlay { get; set; } = new();
protected override void OnParametersSet()
{
if(Inventory.Any())
Inventory = Inventory.OrderBy(x => x.Description).ToList();
}
protected override void OnInitialized()
{
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
StateHasChanged();
}
private async Task OnReorderCallback(string sku)
{
SalesItem = await CatalogRepo.GetSalesItemSku(Company.CountryCode.ToLower(), sku);
ReorderOverlay.Show();
}
private async Task OnSelectedItem(DraftItem draftItem)
{
await OnSelected.InvokeAsync(draftItem);
Hide();
}
public void Show()
{
_modalDisplay = "block;";
_showBackdrop = true;
StateHasChanged();
}
private void Hide()
{
_modalDisplay = "none;";
_showBackdrop = false;
StateHasChanged();
}
public void Dispose()
{
Interceptor.DisposeEvent();
}
}

View file

@ -0,0 +1,126 @@
@*
// 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 Wonky.Client.Helpers
<div class="modal" tabindex="-1" role="dialog" style="display:@_modalDisplay">
@* <div class="modal-dialog modal-dialog-scrollable modal-fullscreen-lg-down modal-xl modal-lg"> *@
<div class="modal-dialog modal-dialog-scrollable modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">@SalesItem.Name @SalesItem.Sku (@SalesItem.BoxSize stk/colli)</h4>
<button type="button" class="btn-close" @onclick="Hide" data-bs-dismiss="modal" aria-label="Luk"></button>
</div>
<div class="modal-body">
@if (SalesItem.Discontinued)
{
<h3>Udgået produkt</h3>
}
else
{
@* draft line ----------------------------------------------------- *@
<div class="row">
<div class="col">
<table id="draft-line" class="table table-bordered">
<thead>
<tr class="bg-dark text-white">
<th scope="col" colspan="6">BESTILLING</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"></th>
</tr>
</thead>
<tbody>
<tr>
<td class="align-middle">
<input type="number" class="form-control" @bind-value="@SelectedItem.Quantity"/>
</td>
<td class="align-middle">
<div class="input-group">
<input type="number" class="form-control" @bind-value="@SelectedItem.Price"/>
</div>
</td>
<td class="align-middle">
<input type="number" class="form-control" @bind-value="@SelectedItem.Discount"/>
</td>
<td class="align-middle align-content-center justify-content-center">
<input type="checkbox" class="form-check" @bind-value="@SelectedItem.Sas"/>
</td>
<td class="align-middle">
<button type="button" class="btn btn-warning text-nowrap d-block" @onclick="@(() => SendToOrder(SelectedItem))">BESTIL</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
@* end draft line ------------------------------------------------- *@
@* price list item ------------------------------------------------ *@
<div class="row align-middle">
@foreach (var rate in SalesItem.Rates)
{
<div class="col">
<a type="button" class="btn btn-primary btn-sm" data-bs-dismiss="modal" @onclick="@(() => SelectPrice(rate.Quantity, rate.Rate))">
@rate.Quantity <i class="bi-at"></i> @rate.Rate/stk
</a>
</div>
}
</div>
@* end price list item -------------------------------------------- *@
}
@* product history ------------------------------------------------ *@
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Dato</th>
<th scope="col">Antal</th>
<th scope="col">Rabat</th>
<th scope="col">Pris</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach (var entry in ProductHistory)
{
<tr>
<td class="align-middle">@entry.DeliveryDate</td>
<td class="align-middle">@entry.Quantity</td>
<td class="align-middle">@entry.Discount</td>
<td class="align-middle">@entry.Price</td>
<td class="align-middle">
@if (!SalesItem.Discontinued)
{
<button type="button" class="btn btn-primary btn-sm" data-bs-dismiss="modal" @onclick="() => SelectHistory(entry)"><i class="bi-plus"></i> VÆLG</button>
}
</td>
</tr>
}
</tbody>
</table>
@* end product history -------------------------------------------- *@
</div>
</div>
</div>
</div>
@if (_showBackdrop)
{
<div class="modal-backdrop fade show"></div>
}

View file

@ -0,0 +1,92 @@
// Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
//
using System.Globalization;
using Microsoft.AspNetCore.Components;
using Wonky.Client.HttpRepository;
using Wonky.Client.Models;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
#pragma warning disable CS8618
namespace Wonky.Client.OverlayOffice;
public partial class OfficeOrderInventoryReorderOverlay
{
[Inject] public ICountryCustomerHistoryRepository HistoryRepo { get; set; }
[Parameter] public CompanyDto Company { get; set; } = new();
[Parameter] public SalesItemView SalesItem { get; set; } = new();
[Parameter] public EventCallback<DraftItem> OnSelected { get; set; }
private List<ProductHistoryView>? ProductHistory { get; set; } = new();
private DraftItem SelectedItem { get; set; } = new();
private string ProductName { get; set; } = "";
private string _modalDisplay = "";
private bool _showBackdrop;
private bool ShowDraft { get; set; }
protected override async Task OnParametersSetAsync()
{
if (string.IsNullOrWhiteSpace(SalesItem.Sku))
return;
ProductHistory = await HistoryRepo.FetchHistorySku(Company.CountryCode, Company.CompanyId, SalesItem.Sku);
if (!ProductHistory.Any())
await Task.Delay(250);
SelectedItem.Item = SalesItem;
SelectedItem.Discount = 0;
SelectedItem.Quantity = 1;
if(SalesItem.Rates.Any())
SelectedItem.Price = decimal.Parse(SalesItem.Rates[0].Rate, CultureInfo.InvariantCulture);
}
private async Task SendToOrder(DraftItem item)
{
SelectedItem = new DraftItem();
await OnSelected.InvokeAsync(item);
Hide();
}
private void SelectPrice(string quantity, string rate)
{
SelectedItem.Discount = 0;
SelectedItem.Price = decimal.Parse(rate, CultureInfo.InvariantCulture);
SelectedItem.Quantity = int.Parse(quantity);
StateHasChanged();
}
private void SelectHistory(ProductHistoryView item)
{
SelectedItem.Discount = item.Discount;
SelectedItem.Price = item.Price;
SelectedItem.Quantity = item.Quantity;
StateHasChanged();
}
public void Show()
{
_modalDisplay = "block;";
_showBackdrop = true;
StateHasChanged();
}
private void Hide()
{
SelectedItem = new DraftItem();
_modalDisplay = "none;";
_showBackdrop = false;
StateHasChanged();
}
}

View file

@ -24,7 +24,7 @@
</div>
<div class="modal-body">
@((MarkupString) BodyMessage)
<CustomerProductCheckListComponent CompanyId="@CompanyId" ProductList="@Products" />
<CustomerProductCheckListComponent CompanyId="@CompanyId" Inventory="@Products" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" @onclick="Hide">Afbryd</button>

View file

@ -35,9 +35,9 @@
</tr>
</thead>
<tbody>
@if (History.Any())
@if (ProductHistory.Any())
{
@foreach (var entry in History)
@foreach (var entry in ProductHistory)
{
<tr>
<td>@entry.DeliveryDate</td>

View file

@ -28,7 +28,7 @@ public partial class ProductPriceHistoryOverlay
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public string Sku { get; set; } = "";
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
private List<ProductHistoryView>? History { get; set; }
private List<ProductHistoryView>? ProductHistory { get; set; }
private string ProductName { get; set; } = "";
private string _modalDisplay = "";
private bool _showBackdrop;
@ -38,10 +38,10 @@ public partial class ProductPriceHistoryOverlay
if (string.IsNullOrWhiteSpace(Sku))
return;
History = await HistoryRepo.FetchHistory(CompanyId, Sku);
if (History.Any())
ProductHistory = await HistoryRepo.FetchHistory(CompanyId, Sku);
if (ProductHistory.Any())
{
ProductName = History[0].Description;
ProductName = ProductHistory[0].Description;
}
}

View file

@ -160,13 +160,21 @@ else
<div class="row g-2 mb-3">
<div class="col-sm-3 d-grid mx-auto">
@*
***************** Invoice history overlay *****************************
*@
<button class="btn btn-danger" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" @onclick="ShowInvoiceOverlay">Faktura</button>
</div>
<div class="col-sm-3 d-grid mx-auto">
@*
***************** Visit hisotry overlay *****************************
*@
<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">
@*
***************** Product Inventory overlay *****************************
*@
<button class="btn btn-success" disabled="@string.IsNullOrWhiteSpace(Activity.ActivityTypeEnum)" @onclick="ShowInventoryOverlay">Produkter</button>
</div>
</div>
@ -182,6 +190,9 @@ else
Ordrekladde <span class="mx-2 draft-expires-msg">Global kladde (udløber efter @(DraftProvider.Draft.TimeToLiveInSeconds / 60)m inaktivitet)</span>
</th>
<th scope="col" class="text-end">
@*
***************** Reset draft *****************************
*@
<button type="button" class="btn btn-danger btn-sm" @onclick="@DeleteDraft" disabled="@(DraftProvider.Draft.Items.Count == 0)"><i class="bi-trash"></i> Slet kladde</button>
</th>
</tr>
@ -212,6 +223,9 @@ else
<input type="checkbox" checked="@cartItem.Sas" disabled/>
</td>
<td class="align-middle text-end">
@*
***************** Remove item *****************************
*@
<button type="button" class="btn btn-danger" @onclick="@(() => RemoveItem(cartItem))"><i class="bi-trash2"></i> Slet Linje</button>
</td>
</tr>
@ -223,6 +237,9 @@ else
<td class="align-middle text-black text-end fw-bold">@($"{DraftProvider.Draft.Total:N2}")</td>
<td></td>
<td class="align-middle text-end">
@*
***************** Price catalot overlay button *****************************
*@
<button class="btn btn-primary" type="button" @onclick="ShowPriceListOverlay">
<i class="bi-plus"></i> Ny linje
</button>
@ -259,6 +276,9 @@ else
<td class="align-middle" style="min-width:200px;">
<div class="input-group">
<input type="number" class="form-control" @bind-value="@Price"/>
@*
***************** Price history overlay button *****************************
*@
<button class="btn btn-warning" type="button" @onclick="ShowPriceHistoryOverlay">
<i class="bi-list-ul"></i>
</button>
@ -272,6 +292,9 @@ else
</td>
<td class="align-middle">@SelectedItem.Sku</td>
<td class="align-middle">
@*
***************** Add item button *****************************
*@
<button type="button" class="btn btn-primary d-block text-sm-center" @onclick="@(() => AddItem(SelectedItem))">@Quantity stk. @SelectedItem.Name</button>
</td>
</tr>
@ -333,28 +356,30 @@ else
<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">
@*
***************** Confirm product check overlay button *****************************
***************** Continue by submitton order to erp *****************************
*@
<button type="button" class="btn btn-warning" @onclick="CallConfirmCheckOverlay" disabled="@(PoFormInvalid || Working)"><i class="bi-cloud-arrow-up"></i> @ButtonText</button>
</div>
</div>
}
<ProductCheckConfirmationOverlay BodyMessage="" CompanyId="@CompanyId" Products="CheckList"
OnOkClicked="ConfirmProductCheckCallback" @ref="ConfirmationCheckOverlay" />
<ConfirmWorkDateModal BodyMessage="@PromptDateConfirm"
OnOkClicked="WorkDateConfirmCallback" @ref="ConfirmWorkDate"/>
<PriceCatalogOverlay CountryCode="@Company.CountryCode.ToLower()"
OnSelected="PriceListCallback" @ref="CatalogOverlay"/>
<ProductHistoryOverlay CompanyId="@CompanyId" ItemSku="@SelectedItem.Sku" @ref="ProductOverlay"/>
<ProductPriceHistoryOverlay CompanyId="@CompanyId" Sku="@SelectedItem.Sku"
OnSelected="PriceHistoryCallback" @ref="PriceOverlay"/>
<PriceCatalogOverlay CountryCode="@Company.CountryCode.ToLower()" OnSelected="PriceListCallback" @ref="CatalogOverlay"/>
<ProductCheckConfirmationOverlay BodyMessage="" CompanyId="@CompanyId" Products="CheckList"
OnOkClicked="ConfirmProductCheckCallback" @ref="ConfirmationCheckOverlay" />
<ProductPriceHistoryOverlay CompanyId="@CompanyId" Sku="@SelectedItem.Sku" OnSelected="PriceHistoryCallback" @ref="PriceOverlay"/>
<CustomerInvoiceListOverlay CustomerInvoices="CompanyInvoices" @ref="InvoiceListOverlay" />
<CustomerActivityListOverlay Activities="Activities" CompanyName="@Company.Name" @ref="ActivityListOverlay" />
<CustomerInventoryListOverlay CompanyName="@Company.Name" CompanyId="@CompanyId" CountryCode="@Company.CountryCode"
OnSelected="OnInventoryCallback" Inventory="Inventory" @ref="InventoryListOverlay" />
<CustomerActivityListOverlay Activities="Activities" CompanyName="@Company.Name" @ref="ActivityListOverlay" />

View file

@ -36,7 +36,8 @@ namespace Wonky.Client.Pages;
public partial class AdvisorActivityCreatePage : IDisposable
{
// Services
// *************************************************************
// Injected services
[Inject] public ILogger<AdvisorActivityCreatePage> Logger { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public UserProfileService ProfileService { get; set; }
@ -49,11 +50,12 @@ public partial class AdvisorActivityCreatePage : IDisposable
[Inject] public IAdvisorReportRepository ReportRepo { get; set; }
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
[Inject] public IUserInfoService UserInfoService { get; set; }
// *************************************************************
// Parameters
[CascadingParameter] private DraftStateProvider DraftProvider { get; set; } = new();
[Parameter] public string CompanyId { get; set; } = "";
// variables
// *************************************************************
// Variables
private readonly JsonSerializerOptions _options = new() {PropertyNameCaseInsensitive = true};
private SalesItemView SelectedItem { get; set; } = new();
private UserProfile UserProfile { get; set; } = new();
@ -74,8 +76,11 @@ public partial class AdvisorActivityCreatePage : IDisposable
private DateTime SelectedDate { get; set; }
private string OldPhone { get; set; } = "";
private string PromptDateConfirm { get; set; } = "";
// OVERLAY PAGES
private string ButtonText { get; set; } = "Gem besøg";
private bool OrgWarning { get; set; }
private const string PromptDemoForgotten = "Har du glemt demo?";
// *************************************************************
// Overlays
private PriceCatalogOverlay CatalogOverlay { get; set; } = new();
private ProductHistoryOverlay ProductOverlay { get; set; } = new();
private ProductPriceHistoryOverlay PriceOverlay { get; set; } = new();
@ -84,16 +89,13 @@ public partial class AdvisorActivityCreatePage : IDisposable
private CustomerInvoiceListOverlay InvoiceListOverlay { get; set; } = new();
private CustomerInventoryListOverlay InventoryListOverlay { get; set; } = new();
private CustomerActivityListOverlay ActivityListOverlay { get; set; } = new();
// *************************************************************
// Lists
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>
@ -187,7 +189,7 @@ public partial class AdvisorActivityCreatePage : IDisposable
InventoryListOverlay.Show();
Inventory = await HistoryRepo.FetchInventory(CompanyId);
Inventory = Inventory.OrderBy(x => x.Description).ToList();
await Task.Delay(500);
}
@ -316,9 +318,6 @@ public partial class AdvisorActivityCreatePage : IDisposable
}
/// <summary>
/// Work Date confirm callback
/// </summary>
private async Task WorkDateConfirmCallback()
{
await ProfileService.SetDateConfirmed(true);
@ -327,10 +326,6 @@ public partial class AdvisorActivityCreatePage : IDisposable
StateHasChanged();
}
/// <summary>
/// Work Date component callback
/// </summary>
/// <param name="workDate"></param>
private async Task WorkDateComponentCallback(string workDate)
{
ReportClosed = await ReportRepo.ReportExist(workDate);
@ -338,18 +333,11 @@ public partial class AdvisorActivityCreatePage : IDisposable
Activity.ActivityDate = workDate;
}
/// <summary>
/// Show Price list modal
/// </summary>
private void ShowPriceListOverlay()
{
CatalogOverlay.Show();
}
/// <summary>
/// Price List modal callback
/// </summary>
/// <param name="sku"></param>
private async Task PriceListCallback(SelectedSku sku)
{
// get selected item
@ -362,19 +350,12 @@ public partial class AdvisorActivityCreatePage : IDisposable
StateHasChanged();
}
/// <summary>
/// Show Price History modal
/// </summary>
private void ShowPriceHistoryOverlay()
{
if(ShowItem)
PriceOverlay.Show();
}
/// <summary>
/// Price History modal callback
/// </summary>
/// <param name="price"></param>
private void PriceHistoryCallback(decimal price)
{
if (price == 0)
@ -383,9 +364,6 @@ public partial class AdvisorActivityCreatePage : IDisposable
StateHasChanged();
}
/// <summary>
/// Validate and Create Activity
/// </summary>
private async Task CreateActivity()
{
// avoid duplication
@ -486,19 +464,12 @@ public partial class AdvisorActivityCreatePage : IDisposable
Toaster.ShowError(result.Message, "ORDRE FEJL");
}
/// <summary>
/// Delete current draft
/// </summary>
private async Task DeleteDraft()
{
await DraftProvider.DeleteDraftAsync();
Activity.ActivityStatusEnum = "noSale";
}
/// <summary>
/// Add item to draft
/// </summary>
/// <param name="salesItem"></param>
private async Task AddItem(SalesItemView salesItem)
{
ShowItem = false;
@ -524,10 +495,6 @@ public partial class AdvisorActivityCreatePage : IDisposable
await DraftProvider.SaveChangesAsync();
}
/// <summary>
/// Remove item from draft
/// </summary>
/// <param name="item"></param>
private async Task RemoveItem(DraftItem item)
{
// remove item
@ -538,11 +505,6 @@ public partial class AdvisorActivityCreatePage : IDisposable
Activity.ActivityStatusEnum = "noSale";
}
/// <summary>
/// Edit Context handle field change
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
{
Logger.LogDebug("ActivityNewPage => HandleFieldChanged => ActivityStatusEnum <= '{}'", Activity.ActivityStatusEnum);
@ -574,11 +536,6 @@ public partial class AdvisorActivityCreatePage : IDisposable
StateHasChanged();
}
/// <summary>
/// Edit Context handle validation change
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ValidationChanged(object sender, ValidationStateChangedEventArgs e)
{
if (string.IsNullOrEmpty(Activity.ActivityTypeEnum) && !ReportClosed)
@ -605,9 +562,6 @@ public partial class AdvisorActivityCreatePage : IDisposable
ActivityContext.OnValidationStateChanged += ValidationChanged;
}
/// <summary>
/// Implement Dispose from IDisposable
/// </summary>
public void Dispose()
{
Interceptor.DisposeEvent();

View file

@ -32,7 +32,7 @@ namespace Wonky.Client.Pages;
public partial class AdvisorCustomerInventoryListPage : IDisposable
{
[Inject] public IAdvisorCustomerHistoryRepository HistoryRepo { get; set; }
[Inject] public IAdvisorCustomerRepository CustomerREpo { get; set; }
[Inject] public IAdvisorCustomerRepository CustomerRepo { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public IToastService Toaster { get; set; }
[Inject] public ILogger<AdvisorCustomerInventoryListPage> Logger { get; set; }
@ -56,7 +56,7 @@ public partial class AdvisorCustomerInventoryListPage : IDisposable
Interceptor.RegisterEvent();
Interceptor.RegisterBeforeSendEvent();
Company = await CustomerREpo.GetCompanyById(CompanyId);
Company = await CustomerRepo.GetCompanyById(CompanyId);
// fetch product inventory
await FetchProductInventory();
@ -96,9 +96,11 @@ public partial class AdvisorCustomerInventoryListPage : IDisposable
Logger.LogDebug("pulling products from backend");
// fetch product history
Inventory = await HistoryRepo.FetchInventory(CompanyId);
// default sort order by description
if (Inventory.Any())
Inventory = Inventory.OrderBy(x => x.Description).ToList();
// send products to storage
await Storage.SetItemAsync($"{Company.CompanyId}-products", Inventory);
await Storage.SetItemAsync($"{Company.CompanyId}-pDate", $"{DateTime.Now:yyyy-MM-dd}");

View file

@ -15,17 +15,17 @@
//
*@
@using Wonky.Client.OverlayCustomer
@using Wonky.Client.OverlayOffice
@using Wonky.Client.OverlayOrderCreate
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Admin,Office,Supervisor,Warehouse")]
@page "/office/customers/{CountryCode}/{CompanyId}/order"
<PageTitle>Telefon Ordre - @Customer.Name - @Customer.Account</PageTitle>
<PageTitle>Telefon Ordre - @Company.Name - @Company.Account</PageTitle>
<div class="row bg-light border-2 border-dark rounded-3 p-3">
<div class="col-sm-8">
<h3>@Customer.Name - @Customer.Account</h3>
<h3>@Company.Name - @Company.Account</h3>
</div>
<div class="col-sm-3">
<h3>@DateTime.Now.ToShortDateString()</h3>
@ -35,7 +35,7 @@
<div class="spinner-grow text-info" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
</div>
</div>
</div>
@ -46,27 +46,27 @@
<div class="col-md-10">
<InputText id="dlvName" class="form-control" @bind-Value="Activity.DlvName"/>
</div>
<label for="dlvAddress1" class="col-md-2 col-form-label">Lev. Adresse</label>
<div class="col-md-10">
<InputText id="dlvAddress1" class="form-control" @bind-Value="Activity.DlvAddress1"/>
</div>
<label for="dlvAddress2" class="col-md-2 col-form-label">Lev. Adresse</label>
<div class="col-md-10">
<InputText id="dlvAddress2" class="form-control" @bind-Value="Activity.DlvAddress2"/>
</div>
<label for="dlvZipCode" class="col-md-2 col-form-label">Lev. Postnr</label>
<div class="col-md-2">
<InputText id="dlvZipCode" class="form-control" @bind-Value="Activity.DlvZipCode"/>
</div>
<label for="dlvCity" class="col-md-2 col-form-label">Lev. Bynavn</label>
<div class="col-md-6">
<InputText id="dlvCity" class="form-control" @bind-Value="Activity.DlvCity"/>
</div>
<label for="yourRef" class="col-sm-2 col-md-2 col-form-label">Indkøber</label>
<div class="col-sm-10 col-md-4">
<InputText id="yourRef" class="form-control" @bind-Value="Activity.YourRef"/>
@ -84,7 +84,7 @@
<InputTextArea id="orderMessage" class="form-control" @bind-Value="Activity.OrderMessage"/>
<ValidationMessage For="@(() => Activity.OrderMessage)"></ValidationMessage>
</div>
<label for="phone" class="col-sm-2 col-md-2 col-form-label">Tlf.</label>
<div class="col-sm-10 col-md-4">
<InputText id="phone" class="form-control" @bind-Value="Activity.Phone"/>
@ -94,21 +94,30 @@
<label class="form-check-label" for="express">Express</label>
</div>
</div>
<div class="col-sm-4 d-grid mx-auto">
@*
***************** Invoice history overlay *****************************
*@
<button class="btn btn-danger" @onclick="ShowInvoiceOverlay">Faktura</button>
</div>
<div class="col-sm-4 d-grid mx-auto">
@*
***************** Visit history overlay *****************************
*@
<button class="btn btn-warning" @onclick="ShowVisitOverlay">Tidl. besøg</button>
</div>
<div class="col-sm-4 d-grid mx-auto">
@*
***************** Product Inventory overlay *****************************
*@
<button class="btn btn-success" @onclick="ShowInventoryOverlay">Produkter</button>
</div>
</div>
<div id="this-draft" >
<div id="this-draft">
@* Order lines -----------------------------------------------------*@
<div class="row">
<div class="col">
@ -119,6 +128,9 @@
Ordrekladde <span class="mx-2 draft-expires-msg">Global kladde (udløber efter @(DraftProvider.Draft.TimeToLiveInSeconds / 60)m inaktivitet)</span>
</th>
<th scope="col" class="text-end">
@*
***************** Reset draft *****************************
*@
<button type="button" class="btn btn-danger btn-sm" @onclick="@DeleteDraft" disabled="@(DraftProvider.Draft.Items.Count == 0)"><i class="bi-trash"></i> Slet kladde</button>
</th>
</tr>
@ -145,6 +157,9 @@
<td class="align-middle text-end">@($"{cartItem.Discount:N2}")</td>
<td class="align-middle text-end">@($"{cartItem.LineTotal:N2}")</td>
<td class="align-middle text-end">
@*
***************** Remove draft line *****************************
*@
<button type="button" class="btn btn-danger" @onclick="@(() => RemoveItem(cartItem))"><i class="bi-trash2"></i> Slet Linje</button>
</td>
</tr>
@ -155,7 +170,10 @@
<td class="align-middle text-black text-end fw-bold">Total</td>
<td class="align-middle text-black text-end fw-bold">@($"{DraftProvider.Draft.Total:N2}")</td>
<td class="align-middle text-end">
<button class="btn btn-primary" type="button" @onclick="CallPriceListModal">
@*
***************** Product Catalog overlay *****************************
*@
<button class="btn btn-primary" type="button" @onclick="ShowCatalogOverlay">
<i class="bi-plus"></i> Ny linje
</button>
</td>
@ -202,8 +220,10 @@
</td>
<td class="align-middle">@SelectedItem.Sku</td>
<td class="align-middle">
@*
***************** Add line to draft *****************************
*@
<button type="button" class="btn btn-primary d-block text-sm-center" @onclick="@(() => AddItem(SelectedItem))">@Quantity stk. @SelectedItem.Name</button>
@* <button type="button" class="btn btn-primary text-nowrap d-block" @onclick="@(() => AddItem(SelectedItem))">BESTIL @SelectedItem.Name</button> *@
</td>
</tr>
</tbody>
@ -213,66 +233,17 @@
</div>
@* end draft line ------------------------------------------------- *@
</div>
@*
<div class="accordion" id="crmActivity">
$1$ Delivery address #1#
<div class="accordion-item" style="@(Activity.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
</button>
</h2>
<div id="deliveryBody" class="accordion-collapse collapse"
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>
<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>
<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>
<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>
<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>
<div class="col-md-10">
<InputText id="dlvCity" class="form-control" @bind-Value="Activity.DlvCity"/>
</div>
</div>
</div>
</div>
</div>
</div>
*@
</EditForm>
<div class="row mt-5 mb-2">
<div class="col-sm-10 text-end">
@*
***************** Submit order to erp system *****************************
*@
<button type="button" class="btn btn-warning" @onclick="CreateActivity" disabled="@(PoFormInvalid || Working)"><i class="bi-plus"></i> Opret ordre</button>
</div>
</div>
<PriceCatalogOverlay @ref="CatalogOverlay" CountryCode="@CountryCode" OnSelected="PriceListCallback"/>
@* <ProductHistoryOverlay @ref="ProductOverlay" CompanyId="@CompanyId" ItemSku="@SelectedItem.Sku"/> *@
@* <ProductPriceHistoryOverlay @ref="PriceOverlay" CompanyId="@CompanyId" Sku="@SelectedItem.Sku" *@
@* OnSelected="PriceHistoryCallback"/> *@
@* <CustomerInvoiceListOverlay @ref="InvoiceListOverlay" CustomerInvoices="CompanyInvoices"/> *@
@* <CustomerInventoryListOverlay @ref="InventoryListOverlay" CompanyName="@Customer.Name" CompanyId="@CompanyId" *@
@* CountryCode="@CountryCode" Inventory="Inventory" *@
@* OnSelected="InventoryCallback"/> *@
@* <CustomerActivityListOverlay @ref="ActivityListOverlay" Activities="Activities" CompanyName="@Customer.Name"/> *@
<OfficeCustomerInvoiceListOverlay @ref="InvoiceListOverlay" Company="Company" InvoiceList="CompanyInvoices"/>
<OfficeCustomerActivityListOverlay @ref="ActivityListOverlay" Company="Company" ActivityList="CompanyActivities"/>
<OfficeOrderInventoryListOverlay @ref="InventoryListOverlay" Company="Company" Inventory="CompanyInventory" OnSelected="InventoryCallback"/>

View file

@ -21,7 +21,7 @@ using Microsoft.AspNetCore.Components.Forms;
using Wonky.Client.HttpInterceptors;
using Wonky.Client.HttpRepository;
using Wonky.Client.Models;
using Wonky.Client.OverlayCustomer;
using Wonky.Client.OverlayOffice;
using Wonky.Client.OverlayOrderCreate;
using Wonky.Client.Shared;
using Wonky.Entity.DTO;
@ -36,11 +36,11 @@ public partial class OfficeOrderCreatePage : IDisposable
// injected services
[Inject] public ILogger<OfficeOrderCreatePage> Logger { get; set; }
[Inject] public HttpInterceptorService Interceptor { get; set; }
[Inject] public ICountryCustomerRepository CustomerRepo { get; set; }
[Inject] public ICountryCustomerHistoryRepository InventoryRepo { get; set; }
[Inject] public ICountryReportRepository ReportRepo { get; set; }
[Inject] public ISystemUserRepository UserRepo { get; set; }
[Inject] public ICountryCatalogRepository Catalog { get; set; }
[Inject] public ICountryCustomerRepository CustomerRepo { get; set; }
[Inject] public ICountryCustomerHistoryRepository HistoryRepo { get; set; }
[Inject] public ICountryActivityRepository ActivityRepo { get; set; }
[Inject] public ISystemUserRepository UserRepo { get; set; }
// --------------------------------------------------------------------
// parameters
@ -52,8 +52,7 @@ public partial class OfficeOrderCreatePage : IDisposable
// private variables
private readonly JsonSerializerOptions _options = new() {PropertyNameCaseInsensitive = true};
// class objects
private CompanyDto Customer { get; set; } = new();
private List<ProductInventoryView> CustomerInventory { get; set; } = new();
private CompanyDto Company { get; set; } = new();
private SalesItemView SelectedItem { get; set; } = new();
private ActivityDto Activity { get; set; } = new();
private UserManagerEditView SalesRep { get; set; } = new();
@ -72,20 +71,15 @@ public partial class OfficeOrderCreatePage : IDisposable
// --------------------------------------------------------------------
// overlays
private PriceCatalogOverlay CatalogOverlay { get; set; } = new();
private ProductHistoryOverlay ProductOverlay { get; set; } = new();
private ProductPriceHistoryOverlay PriceOverlay { get; set; } = new();
private ConfirmWorkDateModal ConfirmWorkDate { get; set; } = new();
private ProductCheckConfirmationOverlay ConfirmationCheckOverlay { get; set; } = new();
private CustomerInvoiceListOverlay InvoiceListOverlay { get; set; } = new();
private CustomerInventoryListOverlay InventoryListOverlay { get; set; } = new();
private CustomerActivityListOverlay ActivityListOverlay { get; set; } = new();
private OfficeCustomerInvoiceListOverlay InvoiceListOverlay { get; set; } = new();
private OfficeCustomerActivityListOverlay ActivityListOverlay { get; set; } = new();
private OfficeOrderInventoryListOverlay InventoryListOverlay { get; set; } = new();
// --------------------------------------------------------------------
// lists
private List<ProductInventoryView> Inventory { get; set; } = new();
private List<ProductInventoryView> CheckList { get; set; } = new();
private List<ProductInventoryView> CompanyInventory { get; set; } = new();
private InvoiceListView CompanyInvoices { get; set; } = new();
private List<ReportItemView> Activities { get; set; } = new();
private List<ReportItemView> CompanyActivities { get; set; } = new();
protected override async Task OnInitializedAsync()
@ -99,23 +93,30 @@ public partial class OfficeOrderCreatePage : IDisposable
ActivityContext.OnValidationStateChanged += ValidationChanged;
// fetch customer
Customer = await CustomerRepo.GetByCustomerId(CountryCode, CompanyId);
Logger.LogDebug("OfficeOrderCreate => Customer => {}", JsonSerializer.Serialize(Customer));
Company = await CustomerRepo.GetByCustomerId(CountryCode, CompanyId);
Logger.LogDebug("OfficeOrderCreate => Customer => {}", JsonSerializer.Serialize(Company));
var today = $"{DateTime.Now:yyyy-MM-dd}";
Activity.ActivityDate = today;
// initiate a sync to ensure up-to-date product history
if (Customer.HistorySync != today)
Logger.LogDebug("OfficeOrderCreate => ");
Customer.HistorySync = await InventoryRepo.RequestErpToCrmSync(CountryCode, CompanyId, Customer.HistorySync);
// fetch customer inventory
CustomerInventory = await InventoryRepo.RequestInventory(CountryCode, CompanyId);
Logger.LogDebug("OfficeOrderCreate => Inventory => {}", JsonSerializer.Serialize(CustomerInventory));
if (Company.HistorySync != today)
{
Company.HistorySync = await HistoryRepo.RequestErpToCrmSync(CountryCode, CompanyId, Company.HistorySync);
Logger.LogDebug("OfficeOrderCreate => RequestErpToCrmSync <= {}", Company.HistorySync);
}
// fetch invoices
CompanyInvoices = await HistoryRepo.RequestInvoiceList(CountryCode, CompanyId);
Logger.LogDebug("OfficeOrderCreate => Invoices => {}", JsonSerializer.Serialize(CompanyInvoices));
// fetch activities
CompanyActivities = await ActivityRepo.RequestActivityList(CompanyId);
Logger.LogDebug("OfficeOrderCreate => Activities => {}", JsonSerializer.Serialize(CompanyActivities));
// fetch inventory
CompanyInventory = await HistoryRepo.RequestInventory(CountryCode, CompanyId);
CompanyInventory = CompanyInventory.OrderBy(x => x.Description).ToList();
Logger.LogDebug("OfficeOrderCreate => Inventory => {}", JsonSerializer.Serialize(CompanyInventory));
// get sales rep info
SalesRep = await UserRepo.GetUserInfo(Customer.SalesRepId);
SalesRep = await UserRepo.GetUserInfo(Company.SalesRepId);
Logger.LogDebug("OfficeOrderCreate => SalesRep => {}", JsonSerializer.Serialize(SalesRep));
// set activity salesRep and countryCode
@ -123,24 +124,24 @@ public partial class OfficeOrderCreatePage : IDisposable
Activity.CountryCode = SalesRep.CountryCode;
// add customer info into activity properties
Activity.Account = Customer.Account;
Activity.VatNumber = Customer.VatNumber;
Activity.Email = Customer.Email;
Activity.Phone = Customer.Phone;
Activity.Mobile = Customer.Mobile;
Activity.Name = Customer.Name;
Activity.Address1 = Customer.Address1;
Activity.Address2 = Customer.Address2;
Activity.ZipCode = Customer.ZipCode;
Activity.City = Customer.City;
Activity.DlvName = Customer.Name;
Activity.DlvAddress1 = Customer.Address1;
Activity.DlvAddress2 = Customer.Address2;
Activity.DlvZipCode = Customer.ZipCode;
Activity.DlvCity = Customer.City;
Activity.BcId = Customer.BcId;
Activity.CompanyId = Customer.CompanyId;
Activity.SalesRepId = Customer.SalesRepId;
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.BcId = Company.BcId;
Activity.CompanyId = Company.CompanyId;
Activity.SalesRepId = Company.SalesRepId;
// setting up activity properties
Activity.ActivityStatusEnum = "noSale";
@ -201,42 +202,33 @@ public partial class OfficeOrderCreatePage : IDisposable
StateHasChanged();
}
private void CallPriceListModal()
private void ShowCatalogOverlay()
{
CatalogOverlay.Show();
}
private void ShowInvoiceOverlay()
{
InvoiceListOverlay.Show();
}
private void ShowVisitOverlay()
{
ActivityListOverlay.Show();
}
private void ShowInventoryOverlay()
{
}
private void CallPriceHistoryModal()
{
InventoryListOverlay.Show();
}
private void CreateActivity()
{
}
private void PriceHistoryCallback()
private void InventoryCallback(DraftItem item)
{
}
private void InventoryCallback()
{
DraftProvider.Draft.Items.Add(item);
StateHasChanged();
}
/// <summary>