503 lines
24 KiB
Plaintext
503 lines
24 KiB
Plaintext
@page "/management-cockpit"
|
|
@using TrafagSalesExporter.Models
|
|
@using TrafagSalesExporter.Services
|
|
@inject IManagementCockpitPageService CockpitPageService
|
|
@inject ISnackbar Snackbar
|
|
@inject IUiTextService UiText
|
|
|
|
<PageTitle>@T("Management Analyse", "Management analysis")</PageTitle>
|
|
|
|
<MudText Typo="Typo.h4" Class="mb-4">@T("Management Analyse", "Management analysis")</MudText>
|
|
|
|
<MudPaper Class="pa-4 mb-4" Elevation="1">
|
|
<MudGrid>
|
|
<MudItem xs="12" md="6">
|
|
<MudSelect T="string" @bind-Value="_selectedFilePath" Label="@T("Vorhandene Excel-Datei", "Available Excel file")" Dense>
|
|
@foreach (var file in _files)
|
|
{
|
|
<MudSelectItem Value="@file.Path">@file.DisplayName</MudSelectItem>
|
|
}
|
|
</MudSelect>
|
|
</MudItem>
|
|
<MudItem xs="12" md="3">
|
|
<MudSelect T="string" @bind-Value="_selectedFileValueField" Label="@T("Summenfeld", "Value field")" Dense>
|
|
@foreach (var option in _valueFieldOptions)
|
|
{
|
|
<MudSelectItem Value="@option.Key">@option.Label</MudSelectItem>
|
|
}
|
|
</MudSelect>
|
|
</MudItem>
|
|
<MudItem xs="12" md="3">
|
|
<MudSelect T="string" @bind-Value="_selectedFileTargetCurrency" Label="@T("Anzeige-Waehrung", "Display currency")" Dense>
|
|
@foreach (var option in _currencyOptions)
|
|
{
|
|
<MudSelectItem Value="@option.Key">@option.Label</MudSelectItem>
|
|
}
|
|
</MudSelect>
|
|
</MudItem>
|
|
<MudItem xs="12">
|
|
<MudStack Row Spacing="2">
|
|
<MudButton Variant="Variant.Outlined" Color="Color.Info" OnClick="ReloadFiles"
|
|
StartIcon="@Icons.Material.Filled.Refresh" Disabled="_loadingFiles">
|
|
@T("Dateien laden", "Load files")
|
|
</MudButton>
|
|
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="Analyze"
|
|
StartIcon="@Icons.Material.Filled.Analytics" Disabled="_analyzing || string.IsNullOrWhiteSpace(_selectedFilePath)">
|
|
@(_analyzing ? T("Analysiere...", "Analyzing...") : T("Cockpit erzeugen", "Build cockpit"))
|
|
</MudButton>
|
|
</MudStack>
|
|
</MudItem>
|
|
</MudGrid>
|
|
</MudPaper>
|
|
|
|
<MudPaper Class="pa-4 mb-4" Elevation="1">
|
|
<MudText Typo="Typo.h6" Class="mb-3">@T("Zentrale Roh-Auswertung", "Central raw analysis")</MudText>
|
|
<MudAlert Severity="Severity.Info" Dense Variant="Variant.Outlined" Class="mb-3">
|
|
@T("Diese Sicht arbeitet direkt auf `CentralSalesRecords`. Summenfeld und Anzeige-Waehrung koennen gewaehlt werden; fachliche Filter wie Intercompany, Budget und Spartenlogik sind weiterhin nicht enthalten.", "This view works directly on `CentralSalesRecords`. Value field and display currency can be selected; business filters such as intercompany, budget and divisional logic are still not included.")
|
|
</MudAlert>
|
|
<MudAlert Severity="Severity.Warning" Dense Variant="Variant.Outlined" Class="mb-3">
|
|
@T("Diese Analyse ist eine Plausibilitaets- und Rohdatensicht. Fuer den verbindlichen Finance-Abgleich bitte `Soll/Ist Vergleich` oder im Endexcel die `Finance | ...`-Spalten verwenden.",
|
|
"This analysis is a plausibility/raw-data view. For the authoritative finance reconciliation, use `Actual/reference comparison` or the `Finance | ...` columns in the final Excel.")
|
|
</MudAlert>
|
|
<MudGrid>
|
|
<MudItem xs="12" md="2">
|
|
<MudSelect T="int" @bind-Value="_selectedCentralYear" Label='@T("Jahr", "Year")' Dense>
|
|
@foreach (var year in _centralYears)
|
|
{
|
|
<MudSelectItem Value="@year">@year</MudSelectItem>
|
|
}
|
|
</MudSelect>
|
|
</MudItem>
|
|
<MudItem xs="12" md="2">
|
|
<MudTextField @bind-Value="_centralLandFilter" Label="@T("Landfilter", "Country filter")" />
|
|
</MudItem>
|
|
<MudItem xs="12" md="2">
|
|
<MudTextField @bind-Value="_centralTscFilter" Label="TSC" />
|
|
</MudItem>
|
|
<MudItem xs="12" md="2">
|
|
<MudSelect T="int?" @bind-Value="_selectedCentralMonth" Label='@T("Monat (optional)", "Month (optional)")' Dense Clearable>
|
|
@foreach (var month in Enumerable.Range(1, 12))
|
|
{
|
|
<MudSelectItem Value="@((int?)month)">@($"{month:D2}")</MudSelectItem>
|
|
}
|
|
</MudSelect>
|
|
</MudItem>
|
|
<MudItem xs="12" md="3">
|
|
<MudSelect T="string" @bind-Value="_selectedCentralValueField" Label="@T("Summenfeld", "Value field")" Dense>
|
|
@foreach (var option in _valueFieldOptions)
|
|
{
|
|
<MudSelectItem Value="@option.Key">@option.Label</MudSelectItem>
|
|
}
|
|
</MudSelect>
|
|
</MudItem>
|
|
<MudItem xs="12" md="3">
|
|
<MudSelect T="string"
|
|
SelectedValues="_selectedCentralAdditionalValueFields"
|
|
SelectedValuesChanged="SetSelectedCentralAdditionalValueFields"
|
|
MultiSelection="true"
|
|
Label="@T("Weitere Summenfelder", "Additional value fields")"
|
|
Dense>
|
|
@foreach (var option in _valueFieldOptions)
|
|
{
|
|
<MudSelectItem Value="@option.Key">@option.Label</MudSelectItem>
|
|
}
|
|
</MudSelect>
|
|
</MudItem>
|
|
<MudItem xs="12" md="2">
|
|
<MudSelect T="string" @bind-Value="_selectedCentralTargetCurrency" Label="@T("Anzeige-Waehrung", "Display currency")" Dense>
|
|
@foreach (var option in _currencyOptions)
|
|
{
|
|
<MudSelectItem Value="@option.Key">@option.Label</MudSelectItem>
|
|
}
|
|
</MudSelect>
|
|
</MudItem>
|
|
<MudItem xs="12">
|
|
<MudStack Row Spacing="2" AlignItems="AlignItems.Center">
|
|
<MudButton Variant="Variant.Filled" Color="Color.Secondary" OnClick="AnalyzeCentral"
|
|
StartIcon="@Icons.Material.Filled.QueryStats" Disabled="_analyzingCentral || _selectedCentralYear == 0">
|
|
@(_analyzingCentral ? T("Analysiere...", "Analyzing...") : T("Zentrale Auswertung laden", "Load central analysis"))
|
|
</MudButton>
|
|
<MudButton Variant="Variant.Outlined" Color="Color.Default" OnClick="ClearCentralScope"
|
|
StartIcon="@Icons.Material.Filled.FilterAltOff">
|
|
@T("Global", "Global")
|
|
</MudButton>
|
|
@if (!string.IsNullOrWhiteSpace(_centralLandFilter) || !string.IsNullOrWhiteSpace(_centralTscFilter))
|
|
{
|
|
<MudChip T="string" Size="Size.Small" Color="Color.Info" Variant="Variant.Outlined">
|
|
@T("Gefiltert", "Filtered"): @($"{(_centralLandFilter ?? "-")} / {(_centralTscFilter ?? "-")}")
|
|
</MudChip>
|
|
}
|
|
</MudStack>
|
|
</MudItem>
|
|
</MudGrid>
|
|
</MudPaper>
|
|
|
|
@if (_result is not null)
|
|
{
|
|
<MudGrid Class="mb-4">
|
|
<MudItem xs="12" md="3"><MudPaper Class="pa-4"><MudText Typo="Typo.caption">@T("Land", "Country")</MudText><MudText Typo="Typo.h6">@_result.Summary.Land</MudText></MudPaper></MudItem>
|
|
<MudItem xs="12" md="3"><MudPaper Class="pa-4"><MudText Typo="Typo.caption">TSC</MudText><MudText Typo="Typo.h6">@_result.Summary.Tsc</MudText></MudPaper></MudItem>
|
|
<MudItem xs="12" md="3"><MudPaper Class="pa-4"><MudText Typo="Typo.caption">@_result.Summary.ValueFieldLabel</MudText><MudText Typo="Typo.h6">@FormatValue(_result.Summary.AggregatedValueTotal, _result.Summary.DisplayCurrency)</MudText></MudPaper></MudItem>
|
|
<MudItem xs="12" md="3"><MudPaper Class="pa-4"><MudText Typo="Typo.caption">@T("Nicht umgerechnet", "Not converted")</MudText><MudText Typo="Typo.h6">@_result.Summary.MissingExchangeRateCount.ToString("N0")</MudText></MudPaper></MudItem>
|
|
</MudGrid>
|
|
|
|
<MudPaper Class="pa-4 mb-4" Elevation="1">
|
|
<MudText Typo="Typo.h6" Class="mb-2">@T("Management Aussagen", "Management statements")</MudText>
|
|
@foreach (var finding in _result.Findings)
|
|
{
|
|
<MudAlert Severity="@MapSeverity(finding.Severity)" Dense Variant="Variant.Outlined" Class="mb-2">
|
|
<b>@finding.Title:</b> @finding.Detail
|
|
</MudAlert>
|
|
}
|
|
</MudPaper>
|
|
|
|
<MudGrid Class="mb-4">
|
|
<MudItem xs="12" md="4">
|
|
<MudPaper Class="pa-4" Elevation="1">
|
|
<MudText Typo="Typo.h6" Class="mb-2">@T("Top Kunden", "Top customers")</MudText>
|
|
@foreach (var item in _result.TopCustomers)
|
|
{
|
|
<MudText Typo="Typo.body2">@($"{item.Label}: {FormatValue(item.Value, _result.Summary.DisplayCurrency)} ({item.SharePercent:F1}%)")</MudText>
|
|
}
|
|
</MudPaper>
|
|
</MudItem>
|
|
<MudItem xs="12" md="4">
|
|
<MudPaper Class="pa-4" Elevation="1">
|
|
<MudText Typo="Typo.h6" Class="mb-2">@T("Top Produktgruppen", "Top product groups")</MudText>
|
|
@foreach (var item in _result.TopProductGroups)
|
|
{
|
|
<MudText Typo="Typo.body2">@($"{item.Label}: {FormatValue(item.Value, _result.Summary.DisplayCurrency)} ({item.SharePercent:F1}%)")</MudText>
|
|
}
|
|
</MudPaper>
|
|
</MudItem>
|
|
<MudItem xs="12" md="4">
|
|
<MudPaper Class="pa-4" Elevation="1">
|
|
<MudText Typo="Typo.h6" Class="mb-2">@T("Top Sales Owner", "Top sales owner")</MudText>
|
|
@foreach (var item in _result.TopSalesEmployees)
|
|
{
|
|
<MudText Typo="Typo.body2">@($"{item.Label}: {FormatValue(item.Value, _result.Summary.DisplayCurrency)} ({item.SharePercent:F1}%)")</MudText>
|
|
}
|
|
</MudPaper>
|
|
</MudItem>
|
|
</MudGrid>
|
|
|
|
<MudPaper Class="pa-4" Elevation="1">
|
|
<MudText Typo="Typo.h6" Class="mb-2">@T("Datenqualitaet", "Data quality")</MudText>
|
|
@foreach (var entry in _result.DataQualityCounts.OrderByDescending(x => x.Value))
|
|
{
|
|
<MudText Typo="Typo.body2">@($"{entry.Key}: {entry.Value}")</MudText>
|
|
}
|
|
</MudPaper>
|
|
}
|
|
|
|
@if (_centralResult is not null)
|
|
{
|
|
<MudGrid Class="mb-4">
|
|
<MudItem xs="12" md="2"><MudPaper Class="pa-4"><MudText Typo="Typo.caption">@T("Zeilen", "Rows")</MudText><MudText Typo="Typo.h6">@_centralResult.Summary.RowCount.ToString("N0")</MudText></MudPaper></MudItem>
|
|
<MudItem xs="12" md="2"><MudPaper Class="pa-4"><MudText Typo="Typo.caption">@T("Rechnungen", "Invoices")</MudText><MudText Typo="Typo.h6">@_centralResult.Summary.InvoiceCount.ToString("N0")</MudText></MudPaper></MudItem>
|
|
<MudItem xs="12" md="2"><MudPaper Class="pa-4"><MudText Typo="Typo.caption">@T("Standorte", "Sites")</MudText><MudText Typo="Typo.h6">@_centralResult.Summary.SiteCount.ToString("N0")</MudText></MudPaper></MudItem>
|
|
<MudItem xs="12" md="2"><MudPaper Class="pa-4"><MudText Typo="Typo.caption">@T("Laender", "Countries")</MudText><MudText Typo="Typo.h6">@_centralResult.Summary.CountryCount.ToString("N0")</MudText></MudPaper></MudItem>
|
|
<MudItem xs="12" md="2"><MudPaper Class="pa-4"><MudText Typo="Typo.caption">@_centralResult.Summary.ValueFieldLabel</MudText><MudText Typo="Typo.h6">@FormatValue(_centralResult.Summary.ValueTotal, _centralResult.Summary.DisplayCurrency)</MudText></MudPaper></MudItem>
|
|
<MudItem xs="12" md="2"><MudPaper Class="pa-4"><MudText Typo="Typo.caption">@T("Nicht umgerechnet", "Not converted")</MudText><MudText Typo="Typo.h6">@_centralResult.Summary.MissingExchangeRateCount.ToString("N0")</MudText></MudPaper></MudItem>
|
|
</MudGrid>
|
|
|
|
<MudPaper Class="pa-4 mb-4" Elevation="1">
|
|
<MudText Typo="Typo.h6" Class="mb-2">@T("Hinweise", "Notes")</MudText>
|
|
@foreach (var notice in _centralResult.Notices)
|
|
{
|
|
<MudAlert Severity="Severity.Info" Dense Variant="Variant.Outlined" Class="mb-2">@notice</MudAlert>
|
|
}
|
|
</MudPaper>
|
|
|
|
<MudGrid Class="mb-4">
|
|
<MudItem xs="12" md="6">
|
|
<MudPaper Class="pa-4" Elevation="1">
|
|
<MudText Typo="Typo.h6" Class="mb-2">@T("Jahreswerte", "Yearly values")</MudText>
|
|
<MudTable Items="_centralResult.YearlyTotals" Dense Hover Striped>
|
|
<HeaderContent>
|
|
<MudTh>@T("Jahr", "Year")</MudTh>
|
|
<MudTh>@T("Waehrung", "Currency")</MudTh>
|
|
<MudTh>@_centralResult.Summary.ValueFieldLabel</MudTh>
|
|
@foreach (var field in _centralResult.AdditionalValueFields)
|
|
{
|
|
<MudTh>@field.Label</MudTh>
|
|
}
|
|
<MudTh>@T("Zeilen", "Rows")</MudTh>
|
|
</HeaderContent>
|
|
<RowTemplate>
|
|
<MudTd>@context.Year</MudTd>
|
|
<MudTd>@context.Currency</MudTd>
|
|
<MudTd>@FormatValue(context.SalesValue, context.Currency)</MudTd>
|
|
@foreach (var field in _centralResult.AdditionalValueFields)
|
|
{
|
|
<MudTd>@FormatAdditionalValue(context, field.Key)</MudTd>
|
|
}
|
|
<MudTd>@context.RowCount.ToString("N0")</MudTd>
|
|
</RowTemplate>
|
|
</MudTable>
|
|
</MudPaper>
|
|
</MudItem>
|
|
<MudItem xs="12" md="6">
|
|
<MudPaper Class="pa-4" Elevation="1">
|
|
<MudText Typo="Typo.h6" Class="mb-2">@T("Monatswerte", "Monthly values")</MudText>
|
|
<MudTable Items="_centralResult.MonthlyTotals" Dense Hover Striped>
|
|
<HeaderContent>
|
|
<MudTh>@T("Monat", "Month")</MudTh>
|
|
<MudTh>@T("Waehrung", "Currency")</MudTh>
|
|
<MudTh>@_centralResult.Summary.ValueFieldLabel</MudTh>
|
|
@foreach (var field in _centralResult.AdditionalValueFields)
|
|
{
|
|
<MudTh>@field.Label</MudTh>
|
|
}
|
|
<MudTh>@T("Zeilen", "Rows")</MudTh>
|
|
</HeaderContent>
|
|
<RowTemplate>
|
|
<MudTd>@context.Label</MudTd>
|
|
<MudTd>@context.Currency</MudTd>
|
|
<MudTd>@FormatValue(context.SalesValue, context.Currency)</MudTd>
|
|
@foreach (var field in _centralResult.AdditionalValueFields)
|
|
{
|
|
<MudTd>@FormatAdditionalValue(context, field.Key)</MudTd>
|
|
}
|
|
<MudTd>@context.RowCount.ToString("N0")</MudTd>
|
|
</RowTemplate>
|
|
</MudTable>
|
|
</MudPaper>
|
|
</MudItem>
|
|
</MudGrid>
|
|
|
|
<MudGrid Class="mb-4">
|
|
<MudItem xs="12" md="6">
|
|
<MudPaper Class="pa-4" Elevation="1">
|
|
<MudText Typo="Typo.h6" Class="mb-2">@T("Tageswerte im ausgewaehlten Monat", "Daily values in selected month")</MudText>
|
|
<MudTable Items="_centralResult.DailyTotals" Dense Hover Striped>
|
|
<HeaderContent>
|
|
<MudTh>@T("Tag", "Day")</MudTh>
|
|
<MudTh>@T("Waehrung", "Currency")</MudTh>
|
|
<MudTh>@_centralResult.Summary.ValueFieldLabel</MudTh>
|
|
@foreach (var field in _centralResult.AdditionalValueFields)
|
|
{
|
|
<MudTh>@field.Label</MudTh>
|
|
}
|
|
<MudTh>@T("Zeilen", "Rows")</MudTh>
|
|
</HeaderContent>
|
|
<RowTemplate>
|
|
<MudTd>@context.Label</MudTd>
|
|
<MudTd>@context.Currency</MudTd>
|
|
<MudTd>@FormatValue(context.SalesValue, context.Currency)</MudTd>
|
|
@foreach (var field in _centralResult.AdditionalValueFields)
|
|
{
|
|
<MudTd>@FormatAdditionalValue(context, field.Key)</MudTd>
|
|
}
|
|
<MudTd>@context.RowCount.ToString("N0")</MudTd>
|
|
</RowTemplate>
|
|
<NoRecordsContent>
|
|
<MudText Typo="Typo.caption">@T("Fuer die Tagessicht bitte zusaetzlich einen Monat waehlen.", "Please select a month as well for the daily view.")</MudText>
|
|
</NoRecordsContent>
|
|
</MudTable>
|
|
</MudPaper>
|
|
</MudItem>
|
|
<MudItem xs="12" md="6">
|
|
<MudPaper Class="pa-4" Elevation="1">
|
|
<MudText Typo="Typo.h6" Class="mb-2">@T("Werte nach Quelle", "Values by source")</MudText>
|
|
<MudTable Items="_centralResult.SourceSystemTotals" Dense Hover Striped>
|
|
<HeaderContent>
|
|
<MudTh>@T("Quelle", "Source")</MudTh>
|
|
<MudTh>@T("Waehrung", "Currency")</MudTh>
|
|
<MudTh>@_centralResult.Summary.ValueFieldLabel</MudTh>
|
|
<MudTh>@T("Rechnungen", "Invoices")</MudTh>
|
|
</HeaderContent>
|
|
<RowTemplate>
|
|
<MudTd>@context.Label</MudTd>
|
|
<MudTd>@context.Currency</MudTd>
|
|
<MudTd>@FormatValue(context.SalesValue, context.Currency)</MudTd>
|
|
<MudTd>@context.InvoiceCount.ToString("N0")</MudTd>
|
|
</RowTemplate>
|
|
</MudTable>
|
|
</MudPaper>
|
|
</MudItem>
|
|
</MudGrid>
|
|
|
|
<MudPaper Class="pa-4" Elevation="1">
|
|
<MudText Typo="Typo.h6" Class="mb-2">@T("Werte nach Land", "Values by country")</MudText>
|
|
<MudTable Items="_centralResult.CountryTotals" Dense Hover Striped>
|
|
<HeaderContent>
|
|
<MudTh>@T("Land", "Country")</MudTh>
|
|
<MudTh>@T("Waehrung", "Currency")</MudTh>
|
|
<MudTh>@_centralResult.Summary.ValueFieldLabel</MudTh>
|
|
<MudTh>@T("Rechnungen", "Invoices")</MudTh>
|
|
<MudTh>@T("Zeilen", "Rows")</MudTh>
|
|
</HeaderContent>
|
|
<RowTemplate>
|
|
<MudTd>@context.Label</MudTd>
|
|
<MudTd>@context.Currency</MudTd>
|
|
<MudTd>@FormatValue(context.SalesValue, context.Currency)</MudTd>
|
|
<MudTd>@context.InvoiceCount.ToString("N0")</MudTd>
|
|
<MudTd>@context.RowCount.ToString("N0")</MudTd>
|
|
</RowTemplate>
|
|
</MudTable>
|
|
</MudPaper>
|
|
}
|
|
|
|
@code {
|
|
private List<ManagementCockpitFileOption> _files = [];
|
|
private List<int> _centralYears = [];
|
|
private List<ManagementCockpitValueFieldOption> _valueFieldOptions = [];
|
|
private readonly List<CurrencySelectOption> _currencyOptions =
|
|
[
|
|
new(ManagementCockpitCurrencyOptions.Eur, "EUR"),
|
|
new(ManagementCockpitCurrencyOptions.Usd, "USD"),
|
|
new(ManagementCockpitCurrencyOptions.Native, "Original")
|
|
];
|
|
private string? _selectedFilePath;
|
|
private ManagementCockpitResult? _result;
|
|
private ManagementCockpitCentralResult? _centralResult;
|
|
private int _selectedCentralYear;
|
|
private int? _selectedCentralMonth;
|
|
private string? _centralLandFilter;
|
|
private string? _centralTscFilter;
|
|
private string _selectedFileValueField = ManagementCockpitValueFieldKeys.SalesPriceValue;
|
|
private string _selectedCentralValueField = ManagementCockpitValueFieldKeys.SalesPriceValue;
|
|
private IEnumerable<string> _selectedCentralAdditionalValueFields = [];
|
|
private string _selectedFileTargetCurrency = ManagementCockpitCurrencyOptions.Eur;
|
|
private string _selectedCentralTargetCurrency = ManagementCockpitCurrencyOptions.Eur;
|
|
private bool _loadingFiles;
|
|
private bool _analyzing;
|
|
private bool _analyzingCentral;
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
var state = await CockpitPageService.InitializeAsync(_selectedFilePath, _selectedCentralYear);
|
|
_files = state.Files;
|
|
_valueFieldOptions = state.ValueFieldOptions;
|
|
_centralYears = state.CentralYears;
|
|
_selectedFilePath = state.SelectedFilePath;
|
|
_selectedCentralYear = state.SelectedCentralYear;
|
|
}
|
|
|
|
private async Task ReloadFiles()
|
|
{
|
|
_loadingFiles = true;
|
|
try
|
|
{
|
|
_files = await CockpitPageService.LoadFilesAsync();
|
|
_selectedFilePath ??= _files.FirstOrDefault()?.Path;
|
|
}
|
|
finally
|
|
{
|
|
_loadingFiles = false;
|
|
}
|
|
}
|
|
|
|
private async Task ReloadCentralYears()
|
|
{
|
|
_centralYears = await CockpitPageService.LoadCentralYearsAsync();
|
|
if (_selectedCentralYear == 0)
|
|
_selectedCentralYear = _centralYears.LastOrDefault();
|
|
}
|
|
|
|
private async Task Analyze()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(_selectedFilePath))
|
|
return;
|
|
|
|
_analyzing = true;
|
|
try
|
|
{
|
|
_result = await CockpitPageService.AnalyzeAsync(_selectedFilePath, new ManagementCockpitAnalysisOptions
|
|
{
|
|
ValueField = _selectedFileValueField,
|
|
TargetCurrency = _selectedFileTargetCurrency
|
|
});
|
|
_centralLandFilter = _result.Summary.Land;
|
|
_centralTscFilter = _result.Summary.Tsc;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add(string.Format(T("Cockpit konnte nicht erzeugt werden: {0}", "Could not build cockpit: {0}"), ex.Message), Severity.Error);
|
|
}
|
|
finally
|
|
{
|
|
_analyzing = false;
|
|
}
|
|
}
|
|
|
|
private async Task AnalyzeCentral()
|
|
{
|
|
if (_selectedCentralYear == 0)
|
|
return;
|
|
|
|
_analyzingCentral = true;
|
|
try
|
|
{
|
|
_centralResult = await CockpitPageService.AnalyzeCentralAsync(_selectedCentralYear, _selectedCentralMonth, new ManagementCockpitAnalysisOptions
|
|
{
|
|
ValueField = _selectedCentralValueField,
|
|
AdditionalValueFields = _selectedCentralAdditionalValueFields.ToList(),
|
|
TargetCurrency = _selectedCentralTargetCurrency,
|
|
LandFilter = _centralLandFilter,
|
|
TscFilter = _centralTscFilter
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add(string.Format(T("Zentrale Auswertung konnte nicht erzeugt werden: {0}", "Could not build central analysis: {0}"), ex.Message), Severity.Error);
|
|
}
|
|
finally
|
|
{
|
|
_analyzingCentral = false;
|
|
}
|
|
}
|
|
|
|
private void ClearCentralScope()
|
|
{
|
|
_centralLandFilter = null;
|
|
_centralTscFilter = null;
|
|
}
|
|
|
|
private static Severity MapSeverity(string severity) => severity switch
|
|
{
|
|
"Warning" => Severity.Warning,
|
|
"Error" => Severity.Error,
|
|
_ => Severity.Info
|
|
};
|
|
|
|
private static string BuildPeriodLabel(ManagementCockpitCentralResult result)
|
|
{
|
|
if (result.Summary.PeriodStart is null || result.Summary.PeriodEnd is null)
|
|
return "-";
|
|
|
|
return $"{result.Summary.PeriodStart.Value:dd.MM.yyyy} - {result.Summary.PeriodEnd.Value:dd.MM.yyyy}";
|
|
}
|
|
|
|
private static string FormatValue(decimal value, string currency)
|
|
=> string.IsNullOrWhiteSpace(currency) || currency == "-"
|
|
? value.ToString("N2")
|
|
: $"{value:N2} {currency}";
|
|
|
|
private void SetSelectedCentralAdditionalValueFields(IEnumerable<string> values)
|
|
{
|
|
_selectedCentralAdditionalValueFields = values
|
|
.Where(value => !string.IsNullOrWhiteSpace(value))
|
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
|
.ToList();
|
|
}
|
|
|
|
private static string FormatAdditionalValue(ManagementCockpitTimeValueRow row, string fieldKey)
|
|
{
|
|
if (!row.AdditionalValues.TryGetValue(fieldKey, out var value))
|
|
return "-";
|
|
|
|
var formattedValue = FormatValue(value.Value, value.Currency);
|
|
return value.MissingExchangeRateCount == 0
|
|
? formattedValue
|
|
: $"{formattedValue} / {value.MissingExchangeRateCount} ohne Kurs";
|
|
}
|
|
|
|
private sealed record CurrencySelectOption(string Key, string Label);
|
|
}
|
|
|
|
@code {
|
|
private string T(string german, string english) => UiText.Text(german, english);
|
|
}
|