print customer statistic with or without price

This commit is contained in:
Frede Hundewadt 2023-08-25 15:35:26 +02:00
parent c5ce40b48e
commit c929e7e17a
10 changed files with 290 additions and 94 deletions

View file

@ -0,0 +1,76 @@
@using Wonky.Client.Models
<table class="table table-striped d-print-table w-100">
<thead>
<tr>
<th class="text-center" colspan="6">
<h2>Produktkøb @CompanyName</h2>
<p>@HeaderGenerated</p>
</th>
</tr>
<tr class="rounded-2 border border-1">
<th scope="col">
Beskrivelse
</th>
<th scope="col">
Vare Nr.
</th>
<th scope="col">
Dato
</th>
<th scope="col">
Antal
</th>
@if (IncludePrice)
{
<th scope="col" class="text-end">
Pris
</th>
<th scope="col" class="text-end">
Afslag
</th>
}
</tr>
</thead>
<tbody>
@foreach (var item in Items)
{
<tr class="align-content-center">
<td>
@item.Description
</td>
<td>
@item.Sku
</td>
<td>
@item.DeliveryDate.ToShortDateString()
</td>
<td>
@item.Quantity
</td>
@if (IncludePrice)
{
<td class="text-end">
@item.Price
</td>
<td class="text-end">
@(item.Discount)%
</td>
}
</tr>
}
</tbody>
</table>
@code {
[Parameter] public string CompanyName { get; set; } = "";
[Parameter] public string HeaderGenerated { get; set; } = "";
[Parameter] public List<InventoryItem> Items { get; set; } = new();
[Parameter] public bool IncludePrice { get; set; }
}

View file

@ -132,7 +132,7 @@ public class CabinetDrawerService : ICabinetDrawerService
if (drawer == null) force = true;
if (!force) return drawer ?? new StatisticDrawer();
var result = await _historyRepo.GetProductInvoiceLines(companyId);
var content = result.Select(x => new HistoryFilter
var content = result.Select(x => new InventoryItem
{
DeliveryDate = DateTime.Parse(x.DeliveryDate),
Description = x.Description,

View file

@ -0,0 +1,9 @@
namespace Wonky.Client.Models;
public class DkStatisticPrint
{
public string DeliveryDate { get; set; } = "";
public string Description { get; set; } = "";
public string Sku { get; set; } = "";
public int Quantity { get; set; }
}

View file

@ -1,6 +1,6 @@
namespace Wonky.Client.Models;
public class HistoryFilter
public class InventoryItem
{
public DateTime DeliveryDate { get; set; }
public string Description { get; set; } = "";

View file

@ -6,5 +6,5 @@ public class StatisticDrawer
{
public const string Label = "Statistic";
public DateTime LastDateModified { get; set; }
public List<HistoryFilter> Content { get; set; } = new();
public List<InventoryItem> Content { get; set; } = new();
}

View file

@ -20,80 +20,27 @@
<PageTitle>Produktkøb @_company.Name</PageTitle>
<div class="row d-print-none pb-3 mb-3 border-bottom">
<div class="col-sm-5"></div>
<div class="col-sm-2 text-end">
<select class="form-select bg-info text-bg-info me-3" @bind-value="Months" @bind-value:event="oninput" @onchange="@OnSelectChanged">
<div class="col-sm-3"></div>
<div class="col-sm-3 text-end">
<select class="form-select bg-info text-bg-info me-3" @bind-value="_months" @bind-value:event="oninput" @onchange="@OnSelectChanged">
<option value="6">Vis 6 måneder</option>
<option value="12">Vis 12 måneder</option>
<option value="18">Vis 18 måneder</option>
<option value="24">Vis 24 måneder</option>
</select>
</div>
<div class="col-sm-5 text-end">
<button type="button" class="btn btn-primary me-3" onclick="window.print();"><i class="bi-printer"></i> Udskriv (24 md.)</button>
<div class="col-sm-6 text-end">
<button type="button" class="btn btn-warning me-3 @(_includePrice ? "active" : "")"
data-bs-toggle="button" aria-pressed="@_includePrice" @onclick="@TogglePrice">
@(_includePrice ? "Uden priser" : "Med priser")
</button>
<button type="button" class="btn btn-primary me-3" @onclick="@PrintReport"><i class="bi-printer"></i> Vis Udskrift</button>
<a class="btn btn-primary" href="/advisor/customers/@CompanyId"><i class="bi-chevron-left"></i> Tilbage</a>
</div>
</div>
@if (DisplayList.Any())
{
<table class="table table-striped d-print-table">
<thead>
<tr>
<th class="text-center" colspan="6">
<h2>Produktkøb @_company.Name</h2>
<p>Dannet @DateTime.Today.ToLongDateString() (@Months md.)</p>
</th>
</tr>
<tr class="rounded-2 border border-1">
<th scope="col">
Beskrivelse
</th>
<th scope="col">
Vare Nr.
</th>
<th scope="col">
Dato
</th>
<th scope="col" class="text-end">
Antal
</th>
<th scope="col" class="text-end">
Pris
</th>
<th scope="col" class="text-end">
Afslag
</th>
</tr>
</thead>
<tbody>
@foreach (var item in DisplayList)
{
<tr class="align-content-center">
<td>
@item.Description
</td>
<td>
@item.Sku
</td>
<td>
@item.DeliveryDate.ToShortDateString()
</td>
<td class="text-end">
@item.Quantity
</td>
<td class="text-end">
@item.Price
</td>
<td class="text-end">
@(item.Discount)%
</td>
</tr>
}
</tbody>
</table>
}
else
{
<div>Ingen data</div>
}
<div class="container">
<AdvisorCustomerStatisticComponent Items="_displayList" CompanyName="@_company.Name"
HeaderGenerated="@_headerGenerated" IncludePrice="_includePrice" />
</div>

View file

@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Components;
using Wonky.Client.Local.Services;
using Wonky.Client.Models;
using Wonky.Entity.DTO;
using Wonky.Entity.Views;
#pragma warning disable CS8618
@ -10,45 +9,83 @@ namespace Wonky.Client.Pages;
public partial class AdvisorCustomerStatisticPage
{
// ##############################################################
[Inject] public ICabinetDrawerService DrawerService { get; set; }
[Inject] public ILogger<AdvisorCustomerStatisticPage> Logger { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
// ##############################################################
[Parameter] public string CompanyId { get; set; } = "";
// ##############################################################
private InfoDrawer _infoDrawer = new();
private StatisticDrawer _statisticDrawer = new();
private List<HistoryFilter> DisplayList { get; set; } = new();
private CompanyDto _company = new();
private int Months { get; set; }
private List<InventoryItem> _displayList = new();
private string _headerGenerated = "";
private string _baseUri = "";
private int _months = 24;
private bool _includePrice = true;
protected override async Task OnInitializedAsync()
{
_infoDrawer = await DrawerService.GetInfoDrawerAsync(CompanyId);
_statisticDrawer = await DrawerService.GetStatisticDrawerAsync(CompanyId);
_company = _infoDrawer.Content;
if (Months == 0)
{
Months = 24;
}
FilterDisplayList(Months);
_baseUri = Navigator.Uri.Split("?")[0];
_displayList = GenerateDisplayList(_months, _includePrice);
UpdateDisplayData(_months, _includePrice);
}
private void FilterDisplayList(int months)
private void PrintReport()
{
if (_statisticDrawer.Content.Any())
{
DisplayList = _statisticDrawer.Content
.Where(x => x.DeliveryDate > DateTime.Now.AddMonths(-months))
.OrderBy(x => x.Description).ThenByDescending(x => x.DeliveryDate)
.ToList();
}
Navigator.NavigateTo($"{_baseUri}/print/{_months}/{_includePrice}");
}
private void TogglePrice()
{
_includePrice = !_includePrice;
UpdateDisplayData(_months, _includePrice);
}
private void OnSelectChanged(ChangeEventArgs e)
{
var val = e.Value?.ToString();
var x = Convert.ToInt32(val);
if (x > 24) x = 24;
FilterDisplayList(x);
var months = Convert.ToInt32(val);
if (months > 24) months = 24;
_months = months;
UpdateDisplayData(_months, _includePrice);
}
private void UpdateDisplayData(int months, bool includePrice)
{
_headerGenerated = $"Dannet {DateTime.Today.ToLongDateString()} ({months} md.)";
_displayList = GenerateDisplayList(months, includePrice);
}
private List<InventoryItem> GenerateDisplayList(int months, bool includePrice)
{
return includePrice
? _statisticDrawer.Content
.Where(x => x.DeliveryDate > DateTime.Now.AddMonths(-months))
.OrderBy(x => x.Description).ThenByDescending(x => x.DeliveryDate)
.ToList()
: _statisticDrawer.Content
.Where(x => x.DeliveryDate > DateTime.Now.AddMonths(-months))
.OrderBy(x => x.Description).ThenByDescending(x => x.DeliveryDate)
.Select(x =>
new InventoryItem
{
DeliveryDate = x.DeliveryDate,
Description = x.Description,
Quantity = x.Quantity,
Sku = x.Sku
}).ToList();
}
}

View file

@ -0,0 +1,36 @@
@* Copyright (C) 2022 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses/agpl-3.0.en.html]
*@
@using Wonky.Client.Components
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles = "Advisor")]
@page "/advisor/customers/{CompanyId}/statistic/print/{Months}/{IncludePrice}"
<PageTitle>Produktkøb @_company.Name</PageTitle>
<div class="row d-print-none">
<div class="col text-end">
<button type="button" class="btn btn-primary me-3" @onclick="@DoPrint"><i class="bi-printer"></i> Print</button>
<button type="button" class="btn btn-secondary me-3" onclick="history.back(1)"><i class="bi-arrow-left"></i> Tilbage</button>
</div>
</div>
<div class="row">
<div class="col">
<AdvisorCustomerStatisticComponent Items="_displayList" CompanyName="@_company.Name"
HeaderGenerated="@_headerGenerated" IncludePrice="_includePrice" />
</div>
</div>

View file

@ -0,0 +1,91 @@
using System.Text.Json;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.JSInterop;
using Wonky.Client.Helpers;
using Wonky.Client.Local.Services;
using Wonky.Client.Models;
using Wonky.Entity.DTO;
#pragma warning disable CS8618
namespace Wonky.Client.Pages;
public partial class AdvisorCustomerStatisticPrintPage
{
// ##############################################################
[Inject] public ICabinetDrawerService DrawerService { get; set; }
[Inject] public ILogger<AdvisorCustomerStatisticPrintPage> Logger { get; set; }
[Inject] public NavigationManager Navigator { get; set; }
[Inject] public IJSRuntime JsRuntime { get; set; }
// ##############################################################
[Parameter] public string CompanyId { get; set; } = "";
[Parameter] public string Months { get; set; }
[Parameter] public string IncludePrice { get; set; }
// ##############################################################
private IJSObjectReference JsModule { get; set; }
private InfoDrawer _infoDrawer = new();
private StatisticDrawer _statisticDrawer = new();
private CompanyDto _company = new();
private List<InventoryItem> _displayList = new();
private string _headerGenerated = "";
private int _months;
private bool _includePrice;
protected override async Task OnInitializedAsync()
{
Logger.LogDebug(Months);
Logger.LogDebug(IncludePrice);
_infoDrawer = await DrawerService.GetInfoDrawerAsync(CompanyId);
_company = _infoDrawer.Content;
_statisticDrawer = await DrawerService.GetStatisticDrawerAsync(CompanyId);
_includePrice = Convert.ToBoolean(IncludePrice);
_months = Convert.ToInt32(Months);
_displayList = GenerateDisplayList(_months, _includePrice);
Logger.LogDebug("{}", JsonSerializer.Serialize(_displayList));
_headerGenerated = $"Dannet {DateTime.Today.ToLongDateString()} ({Months} md.)";
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
JsModule = await JsRuntime
.InvokeAsync<IJSObjectReference>("import", "/scripts/print-invoke.js");
}
}
private async Task DoPrint()
{
await JsModule.InvokeVoidAsync("printInvoke");
}
private List<InventoryItem> GenerateDisplayList(int months, bool includePrice)
{
return includePrice
? _statisticDrawer.Content
.Where(x => x.DeliveryDate > DateTime.Now.AddMonths(-months))
.OrderBy(x => x.Description).ThenByDescending(x => x.DeliveryDate)
.ToList()
: _statisticDrawer.Content
.Where(x => x.DeliveryDate > DateTime.Now.AddMonths(-months))
.OrderBy(x => x.Description).ThenByDescending(x => x.DeliveryDate)
.Select(x =>
new InventoryItem
{
DeliveryDate = x.DeliveryDate,
Description = x.Description,
Quantity = x.Quantity,
Sku = x.Sku
}).ToList();
}
}

View file

@ -1,9 +1,9 @@
{
"appInfo": {
"name": "Wonky Online",
"version": "224.0",
"version": "227.0",
"rc": true,
"sandBox": false,
"sandBox": true,
"image": "grumpy-coder.png",
"sdk": "dotnet 7.0"
},