Add finance details export and translations
This commit is contained in:
@@ -12,18 +12,30 @@
|
|||||||
<MudAppBar Elevation="1" Color="Color.Primary">
|
<MudAppBar Elevation="1" Color="Color.Primary">
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start"
|
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start"
|
||||||
OnClick="ToggleDrawer" />
|
OnClick="ToggleDrawer" />
|
||||||
<MudText Typo="Typo.h6" Class="ml-3 app-title">@T("Trafag Finanze/Sales Management Cockpit", "Trafag Finance/Sales Management Cockpit")</MudText>
|
<MudText Typo="Typo.h6" Class="ml-3 app-title">@T("Trafag Finance/Sales Management Cockpit", "Trafag Finance/Sales Management Cockpit")</MudText>
|
||||||
<MudSpacer />
|
<MudSpacer />
|
||||||
<MudSelect T="string"
|
<MudMenu Class="mr-3 language-menu"
|
||||||
Value="@UiText.CurrentLanguage"
|
AnchorOrigin="Origin.BottomRight"
|
||||||
ValueChanged="ChangeLanguage"
|
TransformOrigin="Origin.TopRight"
|
||||||
Dense
|
Dense>
|
||||||
Variant="Variant.Outlined"
|
<ActivatorContent>
|
||||||
Class="mr-3"
|
<MudButton Variant="Variant.Outlined"
|
||||||
Style="min-width:100px; color:white;">
|
Color="Color.Inherit"
|
||||||
<MudSelectItem Value="@("de")">DE</MudSelectItem>
|
Size="Size.Small"
|
||||||
<MudSelectItem Value="@("en")">EN</MudSelectItem>
|
StartIcon="@Icons.Material.Filled.Translate"
|
||||||
</MudSelect>
|
EndIcon="@Icons.Material.Filled.ExpandMore"
|
||||||
|
Class="language-button">
|
||||||
|
@LanguageLabel
|
||||||
|
</MudButton>
|
||||||
|
</ActivatorContent>
|
||||||
|
<ChildContent>
|
||||||
|
<MudMenuItem OnClick="@(() => ChangeLanguage("de"))">Deutsch</MudMenuItem>
|
||||||
|
<MudMenuItem OnClick="@(() => ChangeLanguage("en"))">English</MudMenuItem>
|
||||||
|
<MudMenuItem OnClick="@(() => ChangeLanguage("es"))">Español</MudMenuItem>
|
||||||
|
<MudMenuItem OnClick="@(() => ChangeLanguage("it"))">Italiano</MudMenuItem>
|
||||||
|
<MudMenuItem OnClick="@(() => ChangeLanguage("hi"))">हिन्दी</MudMenuItem>
|
||||||
|
</ChildContent>
|
||||||
|
</MudMenu>
|
||||||
<AuthorizeView>
|
<AuthorizeView>
|
||||||
<Authorized Context="authState">
|
<Authorized Context="authState">
|
||||||
<MudText Typo="Typo.caption" Class="mr-3">@ShortName(authState.User)</MudText>
|
<MudText Typo="Typo.caption" Class="mr-3">@ShortName(authState.User)</MudText>
|
||||||
@@ -71,6 +83,8 @@
|
|||||||
InvokeAsync(StateHasChanged);
|
InvokeAsync(StateHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string LanguageLabel => UiText.CurrentLanguage.ToUpperInvariant();
|
||||||
|
|
||||||
private string T(string german, string english) => UiText.Text(german, english);
|
private string T(string german, string english) => UiText.Text(german, english);
|
||||||
|
|
||||||
private static string ShortName(ClaimsPrincipal user)
|
private static string ShortName(ClaimsPrincipal user)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@using TrafagSalesExporter.Security
|
@using TrafagSalesExporter.Security
|
||||||
|
@implements IDisposable
|
||||||
@inject TrafagSalesExporter.Services.IUiTextService UiText
|
@inject TrafagSalesExporter.Services.IUiTextService UiText
|
||||||
@inject TrafagSalesExporter.Services.IFinanceCockpitAccessService FinanceAccess
|
@inject TrafagSalesExporter.Services.IFinanceCockpitAccessService FinanceAccess
|
||||||
@inject IConfiguration Configuration
|
@inject IConfiguration Configuration
|
||||||
@@ -58,11 +59,26 @@
|
|||||||
@code {
|
@code {
|
||||||
private bool ShowFinanceComparison => Configuration.GetValue("Navigation:ShowFinanceComparison", true);
|
private bool ShowFinanceComparison => Configuration.GetValue("Navigation:ShowFinanceComparison", true);
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
UiText.Changed += HandleLanguageChanged;
|
||||||
|
}
|
||||||
|
|
||||||
private void LockFinanceCockpit()
|
private void LockFinanceCockpit()
|
||||||
{
|
{
|
||||||
FinanceAccess.Lock();
|
FinanceAccess.Lock();
|
||||||
Navigation.NavigateTo("/");
|
Navigation.NavigateTo("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleLanguageChanged()
|
||||||
|
{
|
||||||
|
InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
|
||||||
private string T(string german, string english) => UiText.Text(german, english);
|
private string T(string german, string english) => UiText.Text(german, english);
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
UiText.Changed -= HandleLanguageChanged;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ public class ConsolidatedExportService : IConsolidatedExportService
|
|||||||
|
|
||||||
await _sharePointService.UploadAsync(
|
await _sharePointService.UploadAsync(
|
||||||
spConfig.TenantId, spConfig.ClientId, spConfig.ClientSecret,
|
spConfig.TenantId, spConfig.ClientId, spConfig.ClientSecret,
|
||||||
spConfig.SiteUrl, sharePointFolder, landSubfolder, consolidatedPath);
|
spConfig.SiteUrl, sharePointFolder, landSubfolder, consolidatedPath,
|
||||||
|
uploadTimestampedCopyIfLocked: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return consolidatedPath;
|
return consolidatedPath;
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ public class ExcelExportService : IExcelExportService
|
|||||||
if (includeFinanceHelpSheet)
|
if (includeFinanceHelpSheet)
|
||||||
{
|
{
|
||||||
AddFinanceSummarySheet(workbook, records, financeRules);
|
AddFinanceSummarySheet(workbook, records, financeRules);
|
||||||
|
AddFinanceDetailsSheet(workbook, records, financeRules);
|
||||||
AddFinanceHelpSheet(workbook);
|
AddFinanceHelpSheet(workbook);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +267,107 @@ public class ExcelExportService : IExcelExportService
|
|||||||
ws.Columns().AdjustToContents();
|
ws.Columns().AdjustToContents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void AddFinanceDetailsSheet(XLWorkbook workbook, List<SalesRecord> records, IReadOnlyList<FinanceRule> financeRules)
|
||||||
|
{
|
||||||
|
var ws = workbook.Worksheets.Add("Finance Details");
|
||||||
|
var financeRuleEngine = new FinanceRuleEngine(financeRules);
|
||||||
|
ws.Position = 2;
|
||||||
|
|
||||||
|
ws.Cell(1, 1).Value = "Finance Details";
|
||||||
|
ws.Cell(1, 1).Style.Font.Bold = true;
|
||||||
|
ws.Cell(1, 1).Style.Font.FontSize = 14;
|
||||||
|
ws.Cell(2, 1).Value = "Diese Zeilen fuehren zur Summe im Blatt Finance Summary. Summe ueber Net Sales Actual bilden.";
|
||||||
|
|
||||||
|
var headers = new[]
|
||||||
|
{
|
||||||
|
"Year",
|
||||||
|
"Country Key",
|
||||||
|
"Currency",
|
||||||
|
"Finance Date",
|
||||||
|
"Net Sales Actual",
|
||||||
|
"Source Value Field",
|
||||||
|
"TSC",
|
||||||
|
"Land",
|
||||||
|
"Document Type",
|
||||||
|
"Invoice Number",
|
||||||
|
"Position on invoice",
|
||||||
|
"Document Entry",
|
||||||
|
"Material",
|
||||||
|
"Name",
|
||||||
|
"Quantity",
|
||||||
|
"Customer number",
|
||||||
|
"Customer name",
|
||||||
|
"Customer country",
|
||||||
|
"Supplier number",
|
||||||
|
"Supplier name",
|
||||||
|
"Supplier country",
|
||||||
|
"posting date",
|
||||||
|
"invoice date",
|
||||||
|
"Sales Price/Value",
|
||||||
|
"Sales Currency",
|
||||||
|
"Document Currency",
|
||||||
|
"Document Total FC",
|
||||||
|
"Document Total LC",
|
||||||
|
"Company Currency"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < headers.Length; i++)
|
||||||
|
{
|
||||||
|
ws.Cell(4, i + 1).Value = headers[i];
|
||||||
|
ws.Cell(4, i + 1).Style.Font.Bold = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rowIndex = 5;
|
||||||
|
foreach (var record in records)
|
||||||
|
{
|
||||||
|
var countryKey = ResolveFinanceCountryKey(record.Land, record.Tsc);
|
||||||
|
var financeDate = financeRuleEngine.ResolveFinanceDate(record, countryKey);
|
||||||
|
var rawInclude = financeRuleEngine.ShouldInclude(record, countryKey);
|
||||||
|
var netSalesActual = financeRuleEngine.ResolveNetSalesActual(record, countryKey, rawInclude);
|
||||||
|
var include = rawInclude && netSalesActual != 0m;
|
||||||
|
|
||||||
|
if (!include)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ws.Cell(rowIndex, 1).Value = financeDate.Year;
|
||||||
|
ws.Cell(rowIndex, 2).Value = countryKey;
|
||||||
|
ws.Cell(rowIndex, 3).Value = ResolveFinanceCurrency(record);
|
||||||
|
ws.Cell(rowIndex, 4).Value = financeDate.ToString("dd.MM.yyyy");
|
||||||
|
ws.Cell(rowIndex, 5).Value = netSalesActual;
|
||||||
|
ws.Cell(rowIndex, 6).Value = "Sales Price/Value";
|
||||||
|
ws.Cell(rowIndex, 7).Value = record.Tsc;
|
||||||
|
ws.Cell(rowIndex, 8).Value = record.Land;
|
||||||
|
ws.Cell(rowIndex, 9).Value = record.DocumentType;
|
||||||
|
ws.Cell(rowIndex, 10).Value = record.InvoiceNumber;
|
||||||
|
ws.Cell(rowIndex, 11).Value = record.PositionOnInvoice;
|
||||||
|
ws.Cell(rowIndex, 12).Value = record.DocumentEntry;
|
||||||
|
ws.Cell(rowIndex, 13).Value = record.Material;
|
||||||
|
ws.Cell(rowIndex, 14).Value = record.Name;
|
||||||
|
ws.Cell(rowIndex, 15).Value = record.Quantity;
|
||||||
|
ws.Cell(rowIndex, 16).Value = record.CustomerNumber;
|
||||||
|
ws.Cell(rowIndex, 17).Value = record.CustomerName;
|
||||||
|
ws.Cell(rowIndex, 18).Value = record.CustomerCountry;
|
||||||
|
ws.Cell(rowIndex, 19).Value = record.SupplierNumber;
|
||||||
|
ws.Cell(rowIndex, 20).Value = record.SupplierName;
|
||||||
|
ws.Cell(rowIndex, 21).Value = record.SupplierCountry;
|
||||||
|
ws.Cell(rowIndex, 22).Value = record.PostingDate?.ToString("dd.MM.yyyy") ?? string.Empty;
|
||||||
|
ws.Cell(rowIndex, 23).Value = record.InvoiceDate?.ToString("dd.MM.yyyy") ?? string.Empty;
|
||||||
|
ws.Cell(rowIndex, 24).Value = record.SalesPriceValue;
|
||||||
|
ws.Cell(rowIndex, 25).Value = record.SalesCurrency;
|
||||||
|
ws.Cell(rowIndex, 26).Value = record.DocumentCurrency;
|
||||||
|
ws.Cell(rowIndex, 27).Value = record.DocumentTotalForeignCurrency;
|
||||||
|
ws.Cell(rowIndex, 28).Value = record.DocumentTotalLocalCurrency;
|
||||||
|
ws.Cell(rowIndex, 29).Value = record.CompanyCurrency;
|
||||||
|
rowIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.Column(5).Style.NumberFormat.Format = "#,##0.00";
|
||||||
|
ws.Column(24).Style.NumberFormat.Format = "#,##0.00";
|
||||||
|
ws.Column(27).Style.NumberFormat.Format = "#,##0.00";
|
||||||
|
ws.Column(28).Style.NumberFormat.Format = "#,##0.00";
|
||||||
|
ws.Columns().AdjustToContents();
|
||||||
|
}
|
||||||
|
|
||||||
private static string BuildFinanceSummaryHint(string countryKey)
|
private static string BuildFinanceSummaryHint(string countryKey)
|
||||||
=> countryKey.ToUpperInvariant() switch
|
=> countryKey.ToUpperInvariant() switch
|
||||||
{
|
{
|
||||||
@@ -290,6 +392,7 @@ public class ExcelExportService : IExcelExportService
|
|||||||
("2. Land filtern", "Finance | Country Key = CH, AT, DE, ES, FR, IN, IT, UK oder US"),
|
("2. Land filtern", "Finance | Country Key = CH, AT, DE, ES, FR, IN, IT, UK oder US"),
|
||||||
("3. Gueltige Zeilen filtern", "Finance | Include = TRUE"),
|
("3. Gueltige Zeilen filtern", "Finance | Include = TRUE"),
|
||||||
("4. Summe bilden", "Finance | Net Sales Actual summieren"),
|
("4. Summe bilden", "Finance | Net Sales Actual summieren"),
|
||||||
|
("Detailblatt", "Finance Details enthaelt nur die Zeilen, die zur Summe im Blatt Finance Summary fuehren."),
|
||||||
("Waehrung", "Finance | Currency zeigt die fuer den Finance-Abgleich fuehrende Hauswaehrung."),
|
("Waehrung", "Finance | Currency zeigt die fuer den Finance-Abgleich fuehrende Hauswaehrung."),
|
||||||
("Datum", "Finance | Date verwendet PostingDate, danach InvoiceDate, danach ExtractionDate. DE Alphaplan wird als Jahresfile 2025 behandelt."),
|
("Datum", "Finance | Date verwendet PostingDate, danach InvoiceDate, danach ExtractionDate. DE Alphaplan wird als Jahresfile 2025 behandelt."),
|
||||||
("Wertquelle", "Finance | Source Value Field zeigt, aus welchem Rohfeld der Finance-Wert kommt."),
|
("Wertquelle", "Finance | Source Value Field zeigt, aus welchem Rohfeld der Finance-Wert kommt."),
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ namespace TrafagSalesExporter.Services;
|
|||||||
|
|
||||||
public interface ISharePointUploadService
|
public interface ISharePointUploadService
|
||||||
{
|
{
|
||||||
Task UploadAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string exportFolder, string land, string localFilePath);
|
Task UploadAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string exportFolder, string land, string localFilePath, bool uploadTimestampedCopyIfLocked = false);
|
||||||
Task<string> DownloadToTempFileAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string fileReference);
|
Task<string> DownloadToTempFileAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string fileReference);
|
||||||
Task<SharePointFileReference> ResolveLatestFileInFolderAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string folderReference, string siteTsc, int? preferredYear = null);
|
Task<SharePointFileReference> ResolveLatestFileInFolderAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string folderReference, string siteTsc, int? preferredYear = null);
|
||||||
Task<IReadOnlyList<SharePointFileReference>> ResolveManualImportFilesInFolderAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string folderReference, string siteTsc, int? preferredYear = null);
|
Task<IReadOnlyList<SharePointFileReference>> ResolveManualImportFilesInFolderAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string folderReference, string siteTsc, int? preferredYear = null);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace TrafagSalesExporter.Services;
|
|||||||
public class SharePointUploadService : ISharePointUploadService
|
public class SharePointUploadService : ISharePointUploadService
|
||||||
{
|
{
|
||||||
public async Task UploadAsync(string tenantId, string clientId, string clientSecret,
|
public async Task UploadAsync(string tenantId, string clientId, string clientSecret,
|
||||||
string siteUrl, string exportFolder, string land, string localFilePath)
|
string siteUrl, string exportFolder, string land, string localFilePath, bool uploadTimestampedCopyIfLocked = false)
|
||||||
{
|
{
|
||||||
var normalizedTenantId = Normalize(tenantId);
|
var normalizedTenantId = Normalize(tenantId);
|
||||||
var normalizedClientId = Normalize(clientId);
|
var normalizedClientId = Normalize(clientId);
|
||||||
@@ -33,17 +33,16 @@ public class SharePointUploadService : ISharePointUploadService
|
|||||||
if (drive?.Id is null)
|
if (drive?.Id is null)
|
||||||
throw new InvalidOperationException("SharePoint Dokumentenbibliothek konnte nicht gefunden werden.");
|
throw new InvalidOperationException("SharePoint Dokumentenbibliothek konnte nicht gefunden werden.");
|
||||||
|
|
||||||
var fileName = Path.GetFileName(localFilePath);
|
var remotePath = BuildUploadPath(normalizedExportFolder, normalizedLand, Path.GetFileName(localFilePath));
|
||||||
var remotePath = string.Join("/",
|
try
|
||||||
new[]
|
{
|
||||||
{
|
await UploadWithLockRetryAsync(graphClient, drive.Id, remotePath, localFilePath);
|
||||||
normalizedExportFolder.Trim('/').Trim(),
|
}
|
||||||
normalizedLand.Trim('/').Trim(),
|
catch (Microsoft.Graph.Models.ODataErrors.ODataError ex) when (uploadTimestampedCopyIfLocked && IsLockedSharePointResource(ex))
|
||||||
fileName
|
{
|
||||||
}.Where(segment => !string.IsNullOrWhiteSpace(segment)));
|
var timestampedPath = BuildUploadPath(normalizedExportFolder, normalizedLand, BuildTimestampedFileName(localFilePath));
|
||||||
|
await UploadWithLockRetryAsync(graphClient, drive.Id, timestampedPath, localFilePath);
|
||||||
await using var stream = File.OpenRead(localFilePath);
|
}
|
||||||
await graphClient.Drives[drive.Id].Root.ItemWithPath(remotePath).Content.PutAsync(stream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> DownloadToTempFileAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string fileReference)
|
public async Task<string> DownloadToTempFileAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string fileReference)
|
||||||
@@ -242,6 +241,45 @@ public class SharePointUploadService : ISharePointUploadService
|
|||||||
|
|
||||||
private static string Normalize(string value) => value?.Trim() ?? string.Empty;
|
private static string Normalize(string value) => value?.Trim() ?? string.Empty;
|
||||||
|
|
||||||
|
private static async Task UploadWithLockRetryAsync(GraphServiceClient graphClient, string driveId, string remotePath, string localFilePath)
|
||||||
|
{
|
||||||
|
const int attempts = 4;
|
||||||
|
for (var attempt = 1; attempt <= attempts; attempt++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await using var stream = File.OpenRead(localFilePath);
|
||||||
|
await graphClient.Drives[driveId].Root.ItemWithPath(remotePath).Content.PutAsync(stream);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (Microsoft.Graph.Models.ODataErrors.ODataError ex) when (attempt < attempts && IsLockedSharePointResource(ex))
|
||||||
|
{
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(5 * attempt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string BuildUploadPath(string exportFolder, string land, string fileName)
|
||||||
|
=> string.Join("/",
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
exportFolder.Trim('/').Trim(),
|
||||||
|
land.Trim('/').Trim(),
|
||||||
|
fileName
|
||||||
|
}.Where(segment => !string.IsNullOrWhiteSpace(segment)));
|
||||||
|
|
||||||
|
private static string BuildTimestampedFileName(string localFilePath)
|
||||||
|
{
|
||||||
|
var name = Path.GetFileNameWithoutExtension(localFilePath);
|
||||||
|
var extension = Path.GetExtension(localFilePath);
|
||||||
|
var timestamp = DateTime.Now.ToString("yyyyMMdd-HHmmss", CultureInfo.InvariantCulture);
|
||||||
|
return $"{name}_{timestamp}{extension}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsLockedSharePointResource(Exception ex)
|
||||||
|
=> ex.Message.Contains("locked", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
ex.ToString().Contains("locked", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
private static string ResolveRemotePath(string fileReference, Uri siteUri)
|
private static string ResolveRemotePath(string fileReference, Uri siteUri)
|
||||||
{
|
{
|
||||||
if (Uri.TryCreate(fileReference, UriKind.Absolute, out var fileUri))
|
if (Uri.TryCreate(fileReference, UriKind.Absolute, out var fileUri))
|
||||||
|
|||||||
@@ -11,6 +11,622 @@ public interface IUiTextService
|
|||||||
public sealed class UiTextService : IUiTextService
|
public sealed class UiTextService : IUiTextService
|
||||||
{
|
{
|
||||||
private string _currentLanguage = "de";
|
private string _currentLanguage = "de";
|
||||||
|
private static readonly HashSet<string> SupportedLanguages = new(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
"de",
|
||||||
|
"en",
|
||||||
|
"es",
|
||||||
|
"it",
|
||||||
|
"hi"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly IReadOnlyDictionary<string, IReadOnlyDictionary<string, string>> Translations =
|
||||||
|
new Dictionary<string, IReadOnlyDictionary<string, string>>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
["es"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
["Trafag Finance/Sales Management Cockpit"] = "Trafag Cockpit de finanzas y ventas",
|
||||||
|
["Finance Cockpit"] = "Cockpit financiero",
|
||||||
|
["Finance Cockpit ist geschuetzt. Bitte separat anmelden."] = "El cockpit financiero está protegido. Inicie sesión por separado.",
|
||||||
|
["Finance-Cockpit-Zugang ist noch nicht konfiguriert. Bitte Username und PasswordHash in FinanceCockpitAccess konfigurieren."] = "El acceso al cockpit financiero aún no está configurado. Configure Username y PasswordHash en FinanceCockpitAccess.",
|
||||||
|
["Export Dashboard"] = "Panel de exportación",
|
||||||
|
["Management Analyse"] = "Análisis de gestión",
|
||||||
|
["Soll/Ist Vergleich"] = "Comparación real/referencia",
|
||||||
|
["Manuelle Importe"] = "Importaciones manuales",
|
||||||
|
["Admin"] = "Administración",
|
||||||
|
["Standorte"] = "Sitios",
|
||||||
|
["Transformationen"] = "Transformaciones",
|
||||||
|
["Finance Regeln"] = "Reglas financieras",
|
||||||
|
["Settings"] = "Configuración",
|
||||||
|
["Logs"] = "Registros",
|
||||||
|
["Finance sperren"] = "Bloquear finanzas",
|
||||||
|
["HR KPI (Login)"] = "KPI RR. HH. (login)",
|
||||||
|
["HR KPI enthaelt sensible Personaldaten. Bitte separat anmelden."] = "HR KPI contiene datos personales sensibles. Inicie sesión por separado.",
|
||||||
|
["HR-KPI-Zugang ist noch nicht konfiguriert. Bitte Username und PasswordHash in HrKpiAccess konfigurieren."] = "El acceso a HR KPI aún no está configurado. Configure Username y PasswordHash en HrKpiAccess.",
|
||||||
|
["HR KPI entsperren"] = "Desbloquear HR KPI",
|
||||||
|
["HR-KPI-Anmeldung fehlgeschlagen."] = "Error al iniciar sesión en HR KPI.",
|
||||||
|
["Name"] = "Nombre",
|
||||||
|
["Passwort"] = "Contraseña",
|
||||||
|
["Finance Cockpit entsperren"] = "Desbloquear cockpit financiero",
|
||||||
|
["Finance-Jahr"] = "Año financiero",
|
||||||
|
["Finance Summary laden"] = "Cargar resumen financiero",
|
||||||
|
["Finance Summary"] = "Resumen financiero",
|
||||||
|
["Net Sales Actual"] = "Ventas netas reales",
|
||||||
|
["gefiltertes Endergebnis"] = "resultado final filtrado",
|
||||||
|
["Enthaltene Zeilen"] = "Filas incluidas",
|
||||||
|
["Finance Include = TRUE"] = "Finance Include = TRUE",
|
||||||
|
["Finance-Regeln"] = "Reglas financieras",
|
||||||
|
["Laender / Waehrungen"] = "Países / monedas",
|
||||||
|
["Summen wie im Excel-Blatt Finance Summary"] = "Totales como en la hoja Excel Finance Summary",
|
||||||
|
["Keine Finance-Summary-Daten fuer diese Filter."] = "No hay datos de resumen financiero para estos filtros.",
|
||||||
|
["Jahresvergleich mit aktuellem Filter"] = "Comparación anual con el filtro actual",
|
||||||
|
["Rohdaten Diagnose"] = "Diagnóstico de datos brutos",
|
||||||
|
["Diese Analyse ist eine Plausibilitaets- und Rohdatensicht. Fuer den verbindlichen Finance-Abgleich bitte `Soll/Ist Vergleich` oder im Endexcel die `Finance | ...`-Spalten verwenden."] = "Este análisis es una vista de plausibilidad y datos brutos. Para la reconciliación financiera vinculante, use `Comparación real/referencia` o las columnas `Finance | ...` en el Excel final.",
|
||||||
|
["Diese Regeln wirken nur auf die Finance-Sicht im zentralen Excel und im Abgleich. Rohdaten und Spaltenmapping bleiben unveraendert."] = "Estas reglas solo afectan la vista financiera en el Excel consolidado y en la reconciliación. Los datos brutos y el mapeo de columnas no cambian.",
|
||||||
|
["Finance-Cockpit-Anmeldung fehlgeschlagen."] = "Error al iniciar sesión en el cockpit financiero.",
|
||||||
|
["Alle exportieren"] = "Exportar todo",
|
||||||
|
["Zentrale Datei neu erzeugen"] = "Reconstruir archivo consolidado",
|
||||||
|
["Aktualisieren"] = "Actualizar",
|
||||||
|
["Lade..."] = "Cargando...",
|
||||||
|
["Speichern"] = "Guardar",
|
||||||
|
["Schliessen"] = "Cerrar",
|
||||||
|
["Regel hinzufuegen"] = "Añadir regla",
|
||||||
|
["Alle speichern"] = "Guardar todo",
|
||||||
|
["Code anzeigen"] = "Mostrar código",
|
||||||
|
["Land"] = "País",
|
||||||
|
["Laender"] = "Países",
|
||||||
|
["Aktiv"] = "Activo",
|
||||||
|
["Aktionen"] = "Acciones",
|
||||||
|
["Status"] = "Estado",
|
||||||
|
["Basis"] = "Base",
|
||||||
|
["Quelle"] = "Fuente",
|
||||||
|
["Schema"] = "Esquema",
|
||||||
|
["Server"] = "Servidor",
|
||||||
|
["Zeilen"] = "Filas",
|
||||||
|
["Rechnungen"] = "Facturas",
|
||||||
|
["Waehrung"] = "Moneda",
|
||||||
|
["Differenz"] = "Diferencia",
|
||||||
|
["Berechnung"] = "Cálculo",
|
||||||
|
["Varianten"] = "Variantes",
|
||||||
|
["Referenz"] = "Referencia",
|
||||||
|
["Ist 2025"] = "Real 2025",
|
||||||
|
["Ampel"] = "Estado",
|
||||||
|
["Ohne Ist"] = "Sin valores reales vacíos",
|
||||||
|
["Varianten anzeigen"] = "mostrar variantes",
|
||||||
|
["Abgrenzung"] = "Alcance",
|
||||||
|
["Wert"] = "Valor",
|
||||||
|
["Jahr"] = "Año",
|
||||||
|
["Monat"] = "Mes",
|
||||||
|
["Tag"] = "Día",
|
||||||
|
["Hinweise"] = "Notas",
|
||||||
|
["Enthalten"] = "Incluido",
|
||||||
|
["Ausgeschlossen"] = "Excluido",
|
||||||
|
["Gefiltert"] = "Filtrado",
|
||||||
|
["Global"] = "Global",
|
||||||
|
["Top Kunden"] = "Clientes principales",
|
||||||
|
["Top Produktgruppen"] = "Grupos de productos principales",
|
||||||
|
["Datenqualitaet"] = "Calidad de datos",
|
||||||
|
["Management Aussagen"] = "Declaraciones de gestión",
|
||||||
|
["Nicht umgerechnet"] = "No convertido",
|
||||||
|
["Jahreswerte"] = "Valores anuales",
|
||||||
|
["Monatswerte"] = "Valores mensuales",
|
||||||
|
["Werte nach Quelle"] = "Valores por fuente",
|
||||||
|
["Werte nach Land"] = "Valores por país",
|
||||||
|
["Rohdaten Diagnose"] = "Diagnóstico de datos brutos",
|
||||||
|
["Vorhandene Excel-Datei"] = "Archivo Excel disponible",
|
||||||
|
["Summenfeld"] = "Campo de valor",
|
||||||
|
["Anzeige-Waehrung"] = "Moneda de visualización",
|
||||||
|
["Dateien laden"] = "Cargar archivos",
|
||||||
|
["Cockpit erzeugen"] = "Crear cockpit",
|
||||||
|
["Zentrale Auswertung laden"] = "Cargar análisis central",
|
||||||
|
["Datei / SharePoint-Ordner"] = "Archivo / carpeta SharePoint",
|
||||||
|
["Letzter Upload"] = "Última carga",
|
||||||
|
["Pfad pruefen"] = "Comprobar ruta",
|
||||||
|
["Importdateien"] = "Archivos de importación",
|
||||||
|
["Anleitung"] = "Guía",
|
||||||
|
["Excel bereitstellen"] = "Preparar Excel",
|
||||||
|
["Speichern und aktivieren"] = "Guardar y activar",
|
||||||
|
["Standort exportieren"] = "Exportar sitio",
|
||||||
|
["Zentrale Excel erzeugen"] = "Crear Excel consolidado",
|
||||||
|
["Finance pruefen"] = "Comprobar finanzas",
|
||||||
|
["Datei hochladen oder SharePoint-/UNC-Pfad eintragen."] = "Cargue un archivo o introduzca una ruta de SharePoint/UNC.",
|
||||||
|
["Pfad pruefen, Standort aktiv setzen und speichern."] = "Compruebe la ruta, active el sitio y guarde.",
|
||||||
|
["Im Export Dashboard den Standort starten. Die Daten landen in CentralSalesRecords."] = "Inicie el sitio en el panel de exportación. Los datos se escriben en CentralSalesRecords.",
|
||||||
|
["Danach `Zentrale Datei neu erzeugen` ausfuehren."] = "Después ejecute `Reconstruir archivo consolidado`.",
|
||||||
|
["Im Endexcel `Finance | ...` oder im Reiter `Soll/Ist Vergleich` kontrollieren."] = "Compruebe las columnas `Finance | ...` en el Excel final o la pestaña `Comparación real/referencia`.",
|
||||||
|
["Richtige Reihenfolge"] = "Orden correcto",
|
||||||
|
["Ein Standortexport aktualisiert die Datenbasis. Die zentrale Excel muss danach neu erzeugt werden."] = "Una exportación de sitio actualiza la base de datos. Después debe reconstruirse el Excel consolidado.",
|
||||||
|
["DE bleibt fachlich offen"] = "DE sigue pendiente a nivel funcional",
|
||||||
|
["Alphaplan ist technisch importierbar. Kundenlaender und Filter fuer den offiziellen DE-Istwert muessen noch bestaetigt werden."] = "Alphaplan puede importarse técnicamente. Los países de cliente y filtros para el valor real oficial de DE aún deben confirmarse.",
|
||||||
|
["Server-Hinweis"] = "Nota del servidor",
|
||||||
|
["Der Server braucht kein Microsoft Excel. XLSX/CSV wird direkt von der Anwendung gelesen."] = "El servidor no necesita Microsoft Excel. La aplicación lee XLSX/CSV directamente.",
|
||||||
|
["Datei hochgeladen."] = "Archivo cargado.",
|
||||||
|
["Upload fehlgeschlagen"] = "Error de carga",
|
||||||
|
["Speichern fehlgeschlagen"] = "Error al guardar",
|
||||||
|
["Ueberblick"] = "Resumen",
|
||||||
|
["Fluktuation"] = "Rotación",
|
||||||
|
["Austritte"] = "Salidas",
|
||||||
|
["Austritte nach Austrittsart"] = "Salidas por tipo",
|
||||||
|
["Austritte nach Organisation"] = "Salidas por organización",
|
||||||
|
["Absenzen"] = "Ausencias",
|
||||||
|
["Absenzen nach Organisation"] = "Ausencias por organización",
|
||||||
|
["Krankheitstage"] = "Días de enfermedad",
|
||||||
|
["Absenzen je Mitarbeiter"] = "Ausencias por empleado",
|
||||||
|
["Personalnr."] = "N.º personal",
|
||||||
|
["Organisation"] = "Organización",
|
||||||
|
["Kurz"] = "Corto",
|
||||||
|
["Lang"] = "Largo",
|
||||||
|
["Gesamt"] = "Total",
|
||||||
|
["Quote"] = "Tasa",
|
||||||
|
["Zeit / Ferien"] = "Tiempo / vacaciones",
|
||||||
|
["Kritische Restferien"] = "Vacaciones restantes críticas",
|
||||||
|
["Rest"] = "Restante",
|
||||||
|
["Ausstehend"] = "Pendiente",
|
||||||
|
["Mitarbeitende"] = "Empleados",
|
||||||
|
["Datenstatus"] = "Estado de datos",
|
||||||
|
["Headcount nach Organisation"] = "Plantilla por organización",
|
||||||
|
["HR-Ampel"] = "Estado RR. HH.",
|
||||||
|
["Schwere"] = "Gravedad",
|
||||||
|
["Bereich"] = "Área",
|
||||||
|
["Pruefpunkt"] = "Comprobación",
|
||||||
|
["Anzahl"] = "Cantidad",
|
||||||
|
["Hinweis"] = "Nota",
|
||||||
|
["Gruppe"] = "Grupo",
|
||||||
|
["Hoechste Absenzen"] = "Ausencias más altas",
|
||||||
|
["Kritische GLZ-Saldi"] = "Saldos horarios críticos",
|
||||||
|
["Saldo"] = "Saldo",
|
||||||
|
["Austritt"] = "Salida",
|
||||||
|
["Austrittsart"] = "Tipo de salida",
|
||||||
|
["Ausschlussgruende"] = "Motivos de exclusión",
|
||||||
|
["Grund"] = "Motivo",
|
||||||
|
["Kostenstelle"] = "Centro de coste",
|
||||||
|
["Alter"] = "Edad",
|
||||||
|
["Dienstjahre"] = "Años de servicio",
|
||||||
|
["Typ"] = "Tipo",
|
||||||
|
["Dateistatus"] = "Estado de archivos",
|
||||||
|
["Stand"] = "Modificado",
|
||||||
|
["Rexx exportieren"] = "Exportar desde Rexx",
|
||||||
|
["Die benoetigten Rexx-Abfragen manuell herunterladen. Excel/XLSX verwenden, nicht PDF."] = "Descargue manualmente las consultas Rexx necesarias. Use Excel/XLSX, no PDF.",
|
||||||
|
["Dateien ablegen"] = "Guardar archivos",
|
||||||
|
["Downloads in den Datenordner kopieren und exakt wie unten benennen."] = "Copie las descargas en la carpeta de datos y nómbrelas exactamente como se indica abajo.",
|
||||||
|
["Cockpit laden"] = "Cargar cockpit",
|
||||||
|
["Im HR-KPI-Cockpit den Datenordner kontrollieren und Laden klicken."] = "En el cockpit HR KPI, compruebe la carpeta de datos y haga clic en Cargar.",
|
||||||
|
["Datenstatus pruefen"] = "Comprobar estado de datos",
|
||||||
|
["Im Reiter Datenstatus muessen die erwarteten Dateien gruen erscheinen."] = "En la pestaña Estado de datos, los archivos esperados deben aparecer en verde.",
|
||||||
|
["Datenordner"] = "Carpeta de datos",
|
||||||
|
["Der Standardordner ist konfigurierbar. Fuer einen anderen Ordner oben im HR-KPI-Filter den Datenordner anpassen und neu laden."] = "La carpeta predeterminada es configurable. Para usar otra carpeta, cambie la carpeta de datos en el filtro HR KPI superior y vuelva a cargar.",
|
||||||
|
["HR-Dateien enthalten Personendaten. Nicht per E-Mail weiterleiten und keine Kopien in ungeschuetzten Ordnern liegen lassen."] = "Los archivos de HR contienen datos personales. No los reenvíe por correo electrónico ni deje copias en carpetas no protegidas.",
|
||||||
|
["Neue Auswertungen im Cockpit"] = "Nuevas vistas en el cockpit",
|
||||||
|
["Managementsicht anonymisiert Personendaten fuer Fuehrungsberichte."] = "La vista de gestión anonimiza los datos personales para informes directivos.",
|
||||||
|
["Dateistatus zeigt Pfad, Zeilen, Aenderungsdatum, Alter und Frische."] = "El estado de archivos muestra ruta, filas, fecha de modificación, antigüedad y frescura.",
|
||||||
|
["HR-Ampel fasst Fluktuation, Krankheit, GLZ, Restferien und Datenqualitaet zusammen."] = "El estado HR resume rotación, enfermedad, saldo horario, vacaciones restantes y calidad de datos.",
|
||||||
|
["GLZ- und Restferien-Ampeln koennen gefiltert werden."] = "Los estados de saldo horario y vacaciones restantes pueden filtrarse.",
|
||||||
|
["Periodenvergleich zeigt die wichtigsten Vorjahreswerte, soweit Daten vorhanden sind."] = "La comparación de periodos muestra los valores clave del año anterior cuando hay datos disponibles.",
|
||||||
|
["Datenqualitaet markiert fehlende Dateien, alte Dateien und auffaellige Werte."] = "La calidad de datos marca archivos faltantes, archivos antiguos y valores llamativos.",
|
||||||
|
["Austritte werden nach Austrittsart und Organisation gruppiert."] = "Las salidas se agrupan por tipo de salida y organización.",
|
||||||
|
["Absenzen werden nach Organisation ausgewertet."] = "Las ausencias se evalúan por organización.",
|
||||||
|
["Top-Absenzen und kritische Detailtabellen helfen bei der operativen Pruefung."] = "Las ausencias principales y tablas críticas ayudan en la revisión operativa.",
|
||||||
|
["Drucken/PDF erzeugt eine weitergebbare Ansicht aus dem Browser."] = "Imprimir/PDF crea una vista compartible desde el navegador.",
|
||||||
|
["Erwartete Dateien"] = "Archivos esperados",
|
||||||
|
["Inhalt"] = "Contenido",
|
||||||
|
["Datei/Pfad"] = "Archivo/ruta",
|
||||||
|
["gefunden"] = "encontrado",
|
||||||
|
["fehlt"] = "falta",
|
||||||
|
["Source Viewer"] = "Visor de código",
|
||||||
|
["Zurueck zur Transformation"] = "Volver a transformaciones",
|
||||||
|
["Datei:"] = "Archivo:",
|
||||||
|
["Klasse:"] = "Clase:",
|
||||||
|
["bei Zeile"] = "en línea",
|
||||||
|
["Kein Dateipfad angegeben."] = "No se indicó ninguna ruta de archivo.",
|
||||||
|
["Ungueltiger Dateipfad."] = "Ruta de archivo no válida.",
|
||||||
|
["Transformer Ansicht"] = "Vista de transformaciones",
|
||||||
|
["Transformationscode"] = "Código de transformación",
|
||||||
|
["Keine Beschreibung."] = "Sin descripción.",
|
||||||
|
["Optionales Argument."] = "Argumento opcional."
|
||||||
|
},
|
||||||
|
["it"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
["Trafag Finance/Sales Management Cockpit"] = "Cockpit Trafag finanza e vendite",
|
||||||
|
["Finance Cockpit"] = "Cockpit finance",
|
||||||
|
["Finance Cockpit ist geschuetzt. Bitte separat anmelden."] = "Il cockpit finance è protetto. Effettuare un accesso separato.",
|
||||||
|
["Finance-Cockpit-Zugang ist noch nicht konfiguriert. Bitte Username und PasswordHash in FinanceCockpitAccess konfigurieren."] = "L'accesso al cockpit finance non è ancora configurato. Configurare Username e PasswordHash in FinanceCockpitAccess.",
|
||||||
|
["Export Dashboard"] = "Dashboard esportazioni",
|
||||||
|
["Management Analyse"] = "Analisi di gestione",
|
||||||
|
["Soll/Ist Vergleich"] = "Confronto consuntivo/riferimento",
|
||||||
|
["Manuelle Importe"] = "Import manuali",
|
||||||
|
["Admin"] = "Amministrazione",
|
||||||
|
["Standorte"] = "Sedi",
|
||||||
|
["Transformationen"] = "Trasformazioni",
|
||||||
|
["Finance Regeln"] = "Regole finance",
|
||||||
|
["Settings"] = "Impostazioni",
|
||||||
|
["Logs"] = "Log",
|
||||||
|
["Finance sperren"] = "Blocca finance",
|
||||||
|
["HR KPI (Login)"] = "KPI HR (login)",
|
||||||
|
["HR KPI enthaelt sensible Personaldaten. Bitte separat anmelden."] = "HR KPI contiene dati personali sensibili. Effettuare un accesso separato.",
|
||||||
|
["HR-KPI-Zugang ist noch nicht konfiguriert. Bitte Username und PasswordHash in HrKpiAccess konfigurieren."] = "L'accesso a HR KPI non è ancora configurato. Configurare Username e PasswordHash in HrKpiAccess.",
|
||||||
|
["HR KPI entsperren"] = "Sblocca HR KPI",
|
||||||
|
["HR-KPI-Anmeldung fehlgeschlagen."] = "Accesso a HR KPI non riuscito.",
|
||||||
|
["Name"] = "Nome",
|
||||||
|
["Passwort"] = "Password",
|
||||||
|
["Finance Cockpit entsperren"] = "Sblocca cockpit finance",
|
||||||
|
["Finance-Jahr"] = "Anno finance",
|
||||||
|
["Finance Summary laden"] = "Carica riepilogo finance",
|
||||||
|
["Finance Summary"] = "Riepilogo finance",
|
||||||
|
["Net Sales Actual"] = "Vendite nette consuntive",
|
||||||
|
["gefiltertes Endergebnis"] = "risultato finale filtrato",
|
||||||
|
["Enthaltene Zeilen"] = "Righe incluse",
|
||||||
|
["Finance Include = TRUE"] = "Finance Include = TRUE",
|
||||||
|
["Finance-Regeln"] = "Regole finance",
|
||||||
|
["Laender / Waehrungen"] = "Paesi / valute",
|
||||||
|
["Summen wie im Excel-Blatt Finance Summary"] = "Totali come nel foglio Excel Finance Summary",
|
||||||
|
["Keine Finance-Summary-Daten fuer diese Filter."] = "Nessun dato di riepilogo finance per questi filtri.",
|
||||||
|
["Jahresvergleich mit aktuellem Filter"] = "Confronto annuale con filtro attuale",
|
||||||
|
["Rohdaten Diagnose"] = "Diagnosi dati grezzi",
|
||||||
|
["Diese Analyse ist eine Plausibilitaets- und Rohdatensicht. Fuer den verbindlichen Finance-Abgleich bitte `Soll/Ist Vergleich` oder im Endexcel die `Finance | ...`-Spalten verwenden."] = "Questa analisi è una vista di plausibilità e dati grezzi. Per la riconciliazione finance vincolante usare `Confronto consuntivo/riferimento` o le colonne `Finance | ...` nell'Excel finale.",
|
||||||
|
["Diese Regeln wirken nur auf die Finance-Sicht im zentralen Excel und im Abgleich. Rohdaten und Spaltenmapping bleiben unveraendert."] = "Queste regole agiscono solo sulla vista finance nell'Excel consolidato e nella riconciliazione. Dati grezzi e mapping colonne restano invariati.",
|
||||||
|
["Finance-Cockpit-Anmeldung fehlgeschlagen."] = "Accesso al cockpit finance non riuscito.",
|
||||||
|
["Alle exportieren"] = "Esporta tutto",
|
||||||
|
["Zentrale Datei neu erzeugen"] = "Ricrea file consolidato",
|
||||||
|
["Aktualisieren"] = "Aggiorna",
|
||||||
|
["Lade..."] = "Caricamento...",
|
||||||
|
["Speichern"] = "Salva",
|
||||||
|
["Schliessen"] = "Chiudi",
|
||||||
|
["Regel hinzufuegen"] = "Aggiungi regola",
|
||||||
|
["Alle speichern"] = "Salva tutto",
|
||||||
|
["Code anzeigen"] = "Mostra codice",
|
||||||
|
["Land"] = "Paese",
|
||||||
|
["Laender"] = "Paesi",
|
||||||
|
["Aktiv"] = "Attivo",
|
||||||
|
["Aktionen"] = "Azioni",
|
||||||
|
["Status"] = "Stato",
|
||||||
|
["Basis"] = "Base",
|
||||||
|
["Quelle"] = "Fonte",
|
||||||
|
["Schema"] = "Schema",
|
||||||
|
["Server"] = "Server",
|
||||||
|
["Zeilen"] = "Righe",
|
||||||
|
["Rechnungen"] = "Fatture",
|
||||||
|
["Waehrung"] = "Valuta",
|
||||||
|
["Differenz"] = "Differenza",
|
||||||
|
["Berechnung"] = "Calcolo",
|
||||||
|
["Varianten"] = "Varianti",
|
||||||
|
["Referenz"] = "Riferimento",
|
||||||
|
["Ist 2025"] = "Consuntivo 2025",
|
||||||
|
["Ampel"] = "Stato",
|
||||||
|
["Ohne Ist"] = "Senza consuntivi vuoti",
|
||||||
|
["Varianten anzeigen"] = "mostra varianti",
|
||||||
|
["Abgrenzung"] = "Ambito",
|
||||||
|
["Wert"] = "Valore",
|
||||||
|
["Jahr"] = "Anno",
|
||||||
|
["Monat"] = "Mese",
|
||||||
|
["Tag"] = "Giorno",
|
||||||
|
["Hinweise"] = "Note",
|
||||||
|
["Enthalten"] = "Incluso",
|
||||||
|
["Ausgeschlossen"] = "Escluso",
|
||||||
|
["Gefiltert"] = "Filtrato",
|
||||||
|
["Global"] = "Globale",
|
||||||
|
["Top Kunden"] = "Clienti principali",
|
||||||
|
["Top Produktgruppen"] = "Gruppi prodotto principali",
|
||||||
|
["Datenqualitaet"] = "Qualità dati",
|
||||||
|
["Management Aussagen"] = "Indicazioni management",
|
||||||
|
["Nicht umgerechnet"] = "Non convertito",
|
||||||
|
["Jahreswerte"] = "Valori annuali",
|
||||||
|
["Monatswerte"] = "Valori mensili",
|
||||||
|
["Werte nach Quelle"] = "Valori per fonte",
|
||||||
|
["Werte nach Land"] = "Valori per paese",
|
||||||
|
["Rohdaten Diagnose"] = "Diagnosi dati grezzi",
|
||||||
|
["Vorhandene Excel-Datei"] = "File Excel disponibile",
|
||||||
|
["Summenfeld"] = "Campo valore",
|
||||||
|
["Anzeige-Waehrung"] = "Valuta visualizzata",
|
||||||
|
["Dateien laden"] = "Carica file",
|
||||||
|
["Cockpit erzeugen"] = "Crea cockpit",
|
||||||
|
["Zentrale Auswertung laden"] = "Carica analisi centrale",
|
||||||
|
["Datei / SharePoint-Ordner"] = "File / cartella SharePoint",
|
||||||
|
["Letzter Upload"] = "Ultimo upload",
|
||||||
|
["Pfad pruefen"] = "Controlla percorso",
|
||||||
|
["Importdateien"] = "File di importazione",
|
||||||
|
["Anleitung"] = "Guida",
|
||||||
|
["Excel bereitstellen"] = "Prepara Excel",
|
||||||
|
["Speichern und aktivieren"] = "Salva e attiva",
|
||||||
|
["Standort exportieren"] = "Esporta sede",
|
||||||
|
["Zentrale Excel erzeugen"] = "Crea Excel consolidato",
|
||||||
|
["Finance pruefen"] = "Controlla finance",
|
||||||
|
["Datei hochladen oder SharePoint-/UNC-Pfad eintragen."] = "Caricare un file o inserire un percorso SharePoint/UNC.",
|
||||||
|
["Pfad pruefen, Standort aktiv setzen und speichern."] = "Controllare il percorso, attivare la sede e salvare.",
|
||||||
|
["Im Export Dashboard den Standort starten. Die Daten landen in CentralSalesRecords."] = "Avviare la sede nel dashboard esportazioni. I dati vengono scritti in CentralSalesRecords.",
|
||||||
|
["Danach `Zentrale Datei neu erzeugen` ausfuehren."] = "Poi eseguire `Ricrea file consolidato`.",
|
||||||
|
["Im Endexcel `Finance | ...` oder im Reiter `Soll/Ist Vergleich` kontrollieren."] = "Controllare le colonne `Finance | ...` nell'Excel finale o la scheda `Confronto consuntivo/riferimento`.",
|
||||||
|
["Richtige Reihenfolge"] = "Sequenza corretta",
|
||||||
|
["Ein Standortexport aktualisiert die Datenbasis. Die zentrale Excel muss danach neu erzeugt werden."] = "L'esportazione di una sede aggiorna la base dati. L'Excel consolidato deve poi essere ricreato.",
|
||||||
|
["DE bleibt fachlich offen"] = "DE resta aperta sul piano funzionale",
|
||||||
|
["Alphaplan ist technisch importierbar. Kundenlaender und Filter fuer den offiziellen DE-Istwert muessen noch bestaetigt werden."] = "Alphaplan è tecnicamente importabile. Paesi cliente e filtri per il valore consuntivo ufficiale DE devono ancora essere confermati.",
|
||||||
|
["Server-Hinweis"] = "Nota server",
|
||||||
|
["Der Server braucht kein Microsoft Excel. XLSX/CSV wird direkt von der Anwendung gelesen."] = "Il server non richiede Microsoft Excel. XLSX/CSV viene letto direttamente dall'applicazione.",
|
||||||
|
["Datei hochgeladen."] = "File caricato.",
|
||||||
|
["Upload fehlgeschlagen"] = "Upload non riuscito",
|
||||||
|
["Speichern fehlgeschlagen"] = "Salvataggio non riuscito",
|
||||||
|
["Ueberblick"] = "Panoramica",
|
||||||
|
["Fluktuation"] = "Turnover",
|
||||||
|
["Austritte"] = "Uscite",
|
||||||
|
["Austritte nach Austrittsart"] = "Uscite per tipo",
|
||||||
|
["Austritte nach Organisation"] = "Uscite per organizzazione",
|
||||||
|
["Absenzen"] = "Assenze",
|
||||||
|
["Absenzen nach Organisation"] = "Assenze per organizzazione",
|
||||||
|
["Krankheitstage"] = "Giorni di malattia",
|
||||||
|
["Absenzen je Mitarbeiter"] = "Assenze per collaboratore",
|
||||||
|
["Personalnr."] = "N. personale",
|
||||||
|
["Organisation"] = "Organizzazione",
|
||||||
|
["Kurz"] = "Breve",
|
||||||
|
["Lang"] = "Lungo",
|
||||||
|
["Gesamt"] = "Totale",
|
||||||
|
["Quote"] = "Tasso",
|
||||||
|
["Zeit / Ferien"] = "Tempo / ferie",
|
||||||
|
["Kritische Restferien"] = "Ferie residue critiche",
|
||||||
|
["Rest"] = "Residuo",
|
||||||
|
["Ausstehend"] = "Aperto",
|
||||||
|
["Mitarbeitende"] = "Collaboratori",
|
||||||
|
["Datenstatus"] = "Stato dati",
|
||||||
|
["Headcount nach Organisation"] = "Organico per organizzazione",
|
||||||
|
["HR-Ampel"] = "Stato HR",
|
||||||
|
["Schwere"] = "Gravità",
|
||||||
|
["Bereich"] = "Area",
|
||||||
|
["Pruefpunkt"] = "Controllo",
|
||||||
|
["Anzahl"] = "Numero",
|
||||||
|
["Hinweis"] = "Nota",
|
||||||
|
["Gruppe"] = "Gruppo",
|
||||||
|
["Hoechste Absenzen"] = "Assenze più alte",
|
||||||
|
["Kritische GLZ-Saldi"] = "Saldi orari critici",
|
||||||
|
["Saldo"] = "Saldo",
|
||||||
|
["Austritt"] = "Uscita",
|
||||||
|
["Austrittsart"] = "Tipo di uscita",
|
||||||
|
["Ausschlussgruende"] = "Motivi di esclusione",
|
||||||
|
["Grund"] = "Motivo",
|
||||||
|
["Kostenstelle"] = "Centro di costo",
|
||||||
|
["Alter"] = "Età",
|
||||||
|
["Dienstjahre"] = "Anni di servizio",
|
||||||
|
["Typ"] = "Tipo",
|
||||||
|
["Dateistatus"] = "Stato file",
|
||||||
|
["Stand"] = "Modificato",
|
||||||
|
["Rexx exportieren"] = "Esporta da Rexx",
|
||||||
|
["Die benoetigten Rexx-Abfragen manuell herunterladen. Excel/XLSX verwenden, nicht PDF."] = "Scaricare manualmente le query Rexx necessarie. Usare Excel/XLSX, non PDF.",
|
||||||
|
["Dateien ablegen"] = "Archivia file",
|
||||||
|
["Downloads in den Datenordner kopieren und exakt wie unten benennen."] = "Copiare i download nella cartella dati e denominarli esattamente come indicato sotto.",
|
||||||
|
["Cockpit laden"] = "Carica cockpit",
|
||||||
|
["Im HR-KPI-Cockpit den Datenordner kontrollieren und Laden klicken."] = "Nel cockpit HR KPI controllare la cartella dati e fare clic su Carica.",
|
||||||
|
["Datenstatus pruefen"] = "Controlla stato dati",
|
||||||
|
["Im Reiter Datenstatus muessen die erwarteten Dateien gruen erscheinen."] = "Nella scheda Stato dati i file attesi devono apparire in verde.",
|
||||||
|
["Datenordner"] = "Cartella dati",
|
||||||
|
["Der Standardordner ist konfigurierbar. Fuer einen anderen Ordner oben im HR-KPI-Filter den Datenordner anpassen und neu laden."] = "La cartella predefinita è configurabile. Per usare un'altra cartella, modificare la cartella dati nel filtro HR KPI in alto e ricaricare.",
|
||||||
|
["HR-Dateien enthalten Personendaten. Nicht per E-Mail weiterleiten und keine Kopien in ungeschuetzten Ordnern liegen lassen."] = "I file HR contengono dati personali. Non inoltrarli via e-mail e non lasciare copie in cartelle non protette.",
|
||||||
|
["Neue Auswertungen im Cockpit"] = "Nuove viste nel cockpit",
|
||||||
|
["Managementsicht anonymisiert Personendaten fuer Fuehrungsberichte."] = "La vista management anonimizza i dati personali per i report direzionali.",
|
||||||
|
["Dateistatus zeigt Pfad, Zeilen, Aenderungsdatum, Alter und Frische."] = "Lo stato file mostra percorso, righe, data modifica, età e freschezza.",
|
||||||
|
["HR-Ampel fasst Fluktuation, Krankheit, GLZ, Restferien und Datenqualitaet zusammen."] = "Lo stato HR riassume turnover, malattia, saldo orario, ferie residue e qualità dati.",
|
||||||
|
["GLZ- und Restferien-Ampeln koennen gefiltert werden."] = "Gli stati di saldo orario e ferie residue possono essere filtrati.",
|
||||||
|
["Periodenvergleich zeigt die wichtigsten Vorjahreswerte, soweit Daten vorhanden sind."] = "Il confronto periodi mostra i principali valori dell'anno precedente quando disponibili.",
|
||||||
|
["Datenqualitaet markiert fehlende Dateien, alte Dateien und auffaellige Werte."] = "La qualità dati segnala file mancanti, file vecchi e valori anomali.",
|
||||||
|
["Austritte werden nach Austrittsart und Organisation gruppiert."] = "Le uscite sono raggruppate per tipo di uscita e organizzazione.",
|
||||||
|
["Absenzen werden nach Organisation ausgewertet."] = "Le assenze sono analizzate per organizzazione.",
|
||||||
|
["Top-Absenzen und kritische Detailtabellen helfen bei der operativen Pruefung."] = "Le assenze principali e le tabelle critiche supportano il controllo operativo.",
|
||||||
|
["Drucken/PDF erzeugt eine weitergebbare Ansicht aus dem Browser."] = "Stampa/PDF crea dal browser una vista condivisibile.",
|
||||||
|
["Erwartete Dateien"] = "File attesi",
|
||||||
|
["Inhalt"] = "Contenuto",
|
||||||
|
["Datei/Pfad"] = "File/percorso",
|
||||||
|
["gefunden"] = "trovato",
|
||||||
|
["fehlt"] = "manca",
|
||||||
|
["Source Viewer"] = "Visualizzatore sorgente",
|
||||||
|
["Zurueck zur Transformation"] = "Torna alle trasformazioni",
|
||||||
|
["Datei:"] = "File:",
|
||||||
|
["Klasse:"] = "Classe:",
|
||||||
|
["bei Zeile"] = "alla riga",
|
||||||
|
["Kein Dateipfad angegeben."] = "Nessun percorso file indicato.",
|
||||||
|
["Ungueltiger Dateipfad."] = "Percorso file non valido.",
|
||||||
|
["Transformer Ansicht"] = "Vista trasformazioni",
|
||||||
|
["Transformationscode"] = "Codice trasformazione",
|
||||||
|
["Keine Beschreibung."] = "Nessuna descrizione.",
|
||||||
|
["Optionales Argument."] = "Argomento opzionale."
|
||||||
|
},
|
||||||
|
["hi"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
["Trafag Finance/Sales Management Cockpit"] = "Trafag वित्त और बिक्री प्रबंधन कॉकपिट",
|
||||||
|
["Finance Cockpit"] = "वित्त कॉकपिट",
|
||||||
|
["Finance Cockpit ist geschuetzt. Bitte separat anmelden."] = "वित्त कॉकपिट सुरक्षित है. कृपया अलग से साइन इन करें.",
|
||||||
|
["Finance-Cockpit-Zugang ist noch nicht konfiguriert. Bitte Username und PasswordHash in FinanceCockpitAccess konfigurieren."] = "वित्त कॉकपिट एक्सेस अभी कॉन्फ़िगर नहीं है. कृपया FinanceCockpitAccess में Username और PasswordHash सेट करें.",
|
||||||
|
["Export Dashboard"] = "निर्यात डैशबोर्ड",
|
||||||
|
["Management Analyse"] = "प्रबंधन विश्लेषण",
|
||||||
|
["Soll/Ist Vergleich"] = "वास्तविक/संदर्भ तुलना",
|
||||||
|
["Manuelle Importe"] = "मैनुअल आयात",
|
||||||
|
["Admin"] = "प्रशासन",
|
||||||
|
["Standorte"] = "साइटें",
|
||||||
|
["Transformationen"] = "रूपांतरण",
|
||||||
|
["Finance Regeln"] = "वित्त नियम",
|
||||||
|
["Settings"] = "सेटिंग्स",
|
||||||
|
["Logs"] = "लॉग",
|
||||||
|
["Finance sperren"] = "वित्त लॉक करें",
|
||||||
|
["HR KPI (Login)"] = "HR KPI (लॉगिन)",
|
||||||
|
["HR KPI enthaelt sensible Personaldaten. Bitte separat anmelden."] = "HR KPI में संवेदनशील कर्मचारी डेटा है. कृपया अलग से साइन इन करें.",
|
||||||
|
["HR-KPI-Zugang ist noch nicht konfiguriert. Bitte Username und PasswordHash in HrKpiAccess konfigurieren."] = "HR KPI एक्सेस अभी कॉन्फ़िगर नहीं है. कृपया HrKpiAccess में Username और PasswordHash सेट करें.",
|
||||||
|
["HR KPI entsperren"] = "HR KPI अनलॉक करें",
|
||||||
|
["HR-KPI-Anmeldung fehlgeschlagen."] = "HR KPI साइन-इन विफल.",
|
||||||
|
["Name"] = "नाम",
|
||||||
|
["Passwort"] = "पासवर्ड",
|
||||||
|
["Finance Cockpit entsperren"] = "वित्त कॉकपिट अनलॉक करें",
|
||||||
|
["Finance-Jahr"] = "वित्त वर्ष",
|
||||||
|
["Finance Summary laden"] = "वित्त सारांश लोड करें",
|
||||||
|
["Finance Summary"] = "वित्त सारांश",
|
||||||
|
["Net Sales Actual"] = "वास्तविक शुद्ध बिक्री",
|
||||||
|
["gefiltertes Endergebnis"] = "फ़िल्टर किया अंतिम परिणाम",
|
||||||
|
["Enthaltene Zeilen"] = "शामिल पंक्तियां",
|
||||||
|
["Finance Include = TRUE"] = "Finance Include = TRUE",
|
||||||
|
["Finance-Regeln"] = "वित्त नियम",
|
||||||
|
["Laender / Waehrungen"] = "देश / मुद्राएं",
|
||||||
|
["Summen wie im Excel-Blatt Finance Summary"] = "Excel शीट Finance Summary जैसे कुल",
|
||||||
|
["Keine Finance-Summary-Daten fuer diese Filter."] = "इन फ़िल्टरों के लिए कोई वित्त सारांश डेटा नहीं है.",
|
||||||
|
["Jahresvergleich mit aktuellem Filter"] = "वर्तमान फ़िल्टर के साथ वार्षिक तुलना",
|
||||||
|
["Rohdaten Diagnose"] = "कच्चे डेटा का निदान",
|
||||||
|
["Diese Analyse ist eine Plausibilitaets- und Rohdatensicht. Fuer den verbindlichen Finance-Abgleich bitte `Soll/Ist Vergleich` oder im Endexcel die `Finance | ...`-Spalten verwenden."] = "यह विश्लेषण विश्वसनीयता और कच्चे डेटा की दृश्य है. बाध्यकारी वित्त मिलान के लिए `वास्तविक/संदर्भ तुलना` या अंतिम Excel में `Finance | ...` कॉलम उपयोग करें.",
|
||||||
|
["Diese Regeln wirken nur auf die Finance-Sicht im zentralen Excel und im Abgleich. Rohdaten und Spaltenmapping bleiben unveraendert."] = "ये नियम केवल केंद्रीय Excel और मिलान की वित्त दृश्य पर लागू होते हैं. कच्चा डेटा और कॉलम मैपिंग अपरिवर्तित रहते हैं.",
|
||||||
|
["Finance-Cockpit-Anmeldung fehlgeschlagen."] = "वित्त कॉकपिट साइन-इन विफल.",
|
||||||
|
["Alle exportieren"] = "सभी निर्यात करें",
|
||||||
|
["Zentrale Datei neu erzeugen"] = "केंद्रीय फ़ाइल फिर बनाएं",
|
||||||
|
["Aktualisieren"] = "ताज़ा करें",
|
||||||
|
["Lade..."] = "लोड हो रहा है...",
|
||||||
|
["Speichern"] = "सहेजें",
|
||||||
|
["Schliessen"] = "बंद करें",
|
||||||
|
["Regel hinzufuegen"] = "नियम जोड़ें",
|
||||||
|
["Alle speichern"] = "सभी सहेजें",
|
||||||
|
["Code anzeigen"] = "कोड दिखाएं",
|
||||||
|
["Land"] = "देश",
|
||||||
|
["Laender"] = "देश",
|
||||||
|
["Aktiv"] = "सक्रिय",
|
||||||
|
["Aktionen"] = "कार्रवाई",
|
||||||
|
["Status"] = "स्थिति",
|
||||||
|
["Basis"] = "आधार",
|
||||||
|
["Quelle"] = "स्रोत",
|
||||||
|
["Schema"] = "स्कीमा",
|
||||||
|
["Server"] = "सर्वर",
|
||||||
|
["Zeilen"] = "पंक्तियां",
|
||||||
|
["Rechnungen"] = "चालान",
|
||||||
|
["Waehrung"] = "मुद्रा",
|
||||||
|
["Differenz"] = "अंतर",
|
||||||
|
["Berechnung"] = "गणना",
|
||||||
|
["Varianten"] = "वेरिएंट",
|
||||||
|
["Referenz"] = "संदर्भ",
|
||||||
|
["Ist 2025"] = "वास्तविक 2025",
|
||||||
|
["Ampel"] = "स्थिति",
|
||||||
|
["Ohne Ist"] = "खाली वास्तविक मानों के बिना",
|
||||||
|
["Varianten anzeigen"] = "वेरिएंट दिखाएं",
|
||||||
|
["Abgrenzung"] = "सीमा",
|
||||||
|
["Wert"] = "मूल्य",
|
||||||
|
["Jahr"] = "वर्ष",
|
||||||
|
["Monat"] = "महीना",
|
||||||
|
["Tag"] = "दिन",
|
||||||
|
["Hinweise"] = "नोट्स",
|
||||||
|
["Enthalten"] = "शामिल",
|
||||||
|
["Ausgeschlossen"] = "बहिष्कृत",
|
||||||
|
["Gefiltert"] = "फ़िल्टर किया गया",
|
||||||
|
["Global"] = "वैश्विक",
|
||||||
|
["Top Kunden"] = "शीर्ष ग्राहक",
|
||||||
|
["Top Produktgruppen"] = "शीर्ष उत्पाद समूह",
|
||||||
|
["Datenqualitaet"] = "डेटा गुणवत्ता",
|
||||||
|
["Management Aussagen"] = "प्रबंधन कथन",
|
||||||
|
["Nicht umgerechnet"] = "परिवर्तित नहीं",
|
||||||
|
["Jahreswerte"] = "वार्षिक मान",
|
||||||
|
["Monatswerte"] = "मासिक मान",
|
||||||
|
["Werte nach Quelle"] = "स्रोत के अनुसार मान",
|
||||||
|
["Werte nach Land"] = "देश के अनुसार मान",
|
||||||
|
["Rohdaten Diagnose"] = "कच्चे डेटा का निदान",
|
||||||
|
["Vorhandene Excel-Datei"] = "उपलब्ध Excel फ़ाइल",
|
||||||
|
["Summenfeld"] = "मान फ़ील्ड",
|
||||||
|
["Anzeige-Waehrung"] = "प्रदर्शन मुद्रा",
|
||||||
|
["Dateien laden"] = "फ़ाइलें लोड करें",
|
||||||
|
["Cockpit erzeugen"] = "कॉकपिट बनाएं",
|
||||||
|
["Zentrale Auswertung laden"] = "केंद्रीय विश्लेषण लोड करें",
|
||||||
|
["Datei / SharePoint-Ordner"] = "फ़ाइल / SharePoint फ़ोल्डर",
|
||||||
|
["Letzter Upload"] = "अंतिम अपलोड",
|
||||||
|
["Pfad pruefen"] = "पथ जांचें",
|
||||||
|
["Importdateien"] = "आयात फ़ाइलें",
|
||||||
|
["Anleitung"] = "गाइड",
|
||||||
|
["Excel bereitstellen"] = "Excel तैयार करें",
|
||||||
|
["Speichern und aktivieren"] = "सहेजें और सक्रिय करें",
|
||||||
|
["Standort exportieren"] = "साइट निर्यात करें",
|
||||||
|
["Zentrale Excel erzeugen"] = "केंद्रीय Excel बनाएं",
|
||||||
|
["Finance pruefen"] = "वित्त जांचें",
|
||||||
|
["Datei hochladen oder SharePoint-/UNC-Pfad eintragen."] = "फ़ाइल अपलोड करें या SharePoint/UNC पथ दर्ज करें.",
|
||||||
|
["Pfad pruefen, Standort aktiv setzen und speichern."] = "पथ जांचें, साइट सक्रिय करें और सहेजें.",
|
||||||
|
["Im Export Dashboard den Standort starten. Die Daten landen in CentralSalesRecords."] = "निर्यात डैशबोर्ड में साइट शुरू करें. डेटा CentralSalesRecords में लिखा जाएगा.",
|
||||||
|
["Danach `Zentrale Datei neu erzeugen` ausfuehren."] = "इसके बाद `केंद्रीय फ़ाइल फिर बनाएं` चलाएं.",
|
||||||
|
["Im Endexcel `Finance | ...` oder im Reiter `Soll/Ist Vergleich` kontrollieren."] = "अंतिम Excel में `Finance | ...` कॉलम या `वास्तविक/संदर्भ तुलना` टैब जांचें.",
|
||||||
|
["Richtige Reihenfolge"] = "सही क्रम",
|
||||||
|
["Ein Standortexport aktualisiert die Datenbasis. Die zentrale Excel muss danach neu erzeugt werden."] = "साइट निर्यात डेटा आधार अपडेट करता है. इसके बाद केंद्रीय Excel फिर बनाना होगा.",
|
||||||
|
["DE bleibt fachlich offen"] = "DE कार्यात्मक रूप से अभी खुला है",
|
||||||
|
["Alphaplan ist technisch importierbar. Kundenlaender und Filter fuer den offiziellen DE-Istwert muessen noch bestaetigt werden."] = "Alphaplan तकनीकी रूप से आयात योग्य है. आधिकारिक DE वास्तविक मान के लिए ग्राहक देश और फ़िल्टर अभी पुष्टि करने हैं.",
|
||||||
|
["Server-Hinweis"] = "सर्वर नोट",
|
||||||
|
["Der Server braucht kein Microsoft Excel. XLSX/CSV wird direkt von der Anwendung gelesen."] = "सर्वर को Microsoft Excel की आवश्यकता नहीं है. एप्लिकेशन XLSX/CSV सीधे पढ़ता है.",
|
||||||
|
["Datei hochgeladen."] = "फ़ाइल अपलोड हुई.",
|
||||||
|
["Upload fehlgeschlagen"] = "अपलोड विफल",
|
||||||
|
["Speichern fehlgeschlagen"] = "सहेजना विफल",
|
||||||
|
["Ueberblick"] = "अवलोकन",
|
||||||
|
["Fluktuation"] = "टर्नओवर",
|
||||||
|
["Austritte"] = "निकास",
|
||||||
|
["Austritte nach Austrittsart"] = "निकास प्रकार के अनुसार",
|
||||||
|
["Austritte nach Organisation"] = "संगठन के अनुसार निकास",
|
||||||
|
["Absenzen"] = "अनुपस्थिति",
|
||||||
|
["Absenzen nach Organisation"] = "संगठन के अनुसार अनुपस्थिति",
|
||||||
|
["Krankheitstage"] = "बीमारी के दिन",
|
||||||
|
["Absenzen je Mitarbeiter"] = "कर्मचारी के अनुसार अनुपस्थिति",
|
||||||
|
["Personalnr."] = "कर्मचारी संख्या",
|
||||||
|
["Organisation"] = "संगठन",
|
||||||
|
["Kurz"] = "छोटा",
|
||||||
|
["Lang"] = "लंबा",
|
||||||
|
["Gesamt"] = "कुल",
|
||||||
|
["Quote"] = "दर",
|
||||||
|
["Zeit / Ferien"] = "समय / छुट्टी",
|
||||||
|
["Kritische Restferien"] = "महत्वपूर्ण बची छुट्टी",
|
||||||
|
["Rest"] = "शेष",
|
||||||
|
["Ausstehend"] = "बकाया",
|
||||||
|
["Mitarbeitende"] = "कर्मचारी",
|
||||||
|
["Datenstatus"] = "डेटा स्थिति",
|
||||||
|
["Headcount nach Organisation"] = "संगठन के अनुसार हेडकाउंट",
|
||||||
|
["HR-Ampel"] = "HR स्थिति",
|
||||||
|
["Schwere"] = "गंभीरता",
|
||||||
|
["Bereich"] = "क्षेत्र",
|
||||||
|
["Pruefpunkt"] = "जांच बिंदु",
|
||||||
|
["Anzahl"] = "संख्या",
|
||||||
|
["Hinweis"] = "नोट",
|
||||||
|
["Gruppe"] = "समूह",
|
||||||
|
["Hoechste Absenzen"] = "सबसे अधिक अनुपस्थिति",
|
||||||
|
["Kritische GLZ-Saldi"] = "महत्वपूर्ण समय शेष",
|
||||||
|
["Saldo"] = "शेष",
|
||||||
|
["Austritt"] = "निकास",
|
||||||
|
["Austrittsart"] = "निकास प्रकार",
|
||||||
|
["Ausschlussgruende"] = "बहिष्करण कारण",
|
||||||
|
["Grund"] = "कारण",
|
||||||
|
["Kostenstelle"] = "लागत केंद्र",
|
||||||
|
["Alter"] = "आयु",
|
||||||
|
["Dienstjahre"] = "सेवा वर्ष",
|
||||||
|
["Typ"] = "प्रकार",
|
||||||
|
["Dateistatus"] = "फ़ाइल स्थिति",
|
||||||
|
["Stand"] = "संशोधित",
|
||||||
|
["Rexx exportieren"] = "Rexx से निर्यात करें",
|
||||||
|
["Die benoetigten Rexx-Abfragen manuell herunterladen. Excel/XLSX verwenden, nicht PDF."] = "ज़रूरी Rexx क्वेरी मैन्युअल रूप से डाउनलोड करें. Excel/XLSX इस्तेमाल करें, PDF नहीं.",
|
||||||
|
["Dateien ablegen"] = "फ़ाइलें रखें",
|
||||||
|
["Downloads in den Datenordner kopieren und exakt wie unten benennen."] = "डाउनलोड को डेटा फ़ोल्डर में कॉपी करें और नीचे दिए गए नामों से ही सहेजें.",
|
||||||
|
["Cockpit laden"] = "कॉकपिट लोड करें",
|
||||||
|
["Im HR-KPI-Cockpit den Datenordner kontrollieren und Laden klicken."] = "HR-KPI कॉकपिट में डेटा फ़ोल्डर जांचें और लोड पर क्लिक करें.",
|
||||||
|
["Datenstatus pruefen"] = "डेटा स्थिति जांचें",
|
||||||
|
["Im Reiter Datenstatus muessen die erwarteten Dateien gruen erscheinen."] = "डेटा स्थिति टैब में अपेक्षित फ़ाइलें हरी दिखनी चाहिए.",
|
||||||
|
["Datenordner"] = "डेटा फ़ोल्डर",
|
||||||
|
["Der Standardordner ist konfigurierbar. Fuer einen anderen Ordner oben im HR-KPI-Filter den Datenordner anpassen und neu laden."] = "डिफ़ॉल्ट फ़ोल्डर कॉन्फ़िगर किया जा सकता है. दूसरा फ़ोल्डर उपयोग करने के लिए ऊपर HR KPI फ़िल्टर में डेटा फ़ोल्डर बदलें और फिर लोड करें.",
|
||||||
|
["HR-Dateien enthalten Personendaten. Nicht per E-Mail weiterleiten und keine Kopien in ungeschuetzten Ordnern liegen lassen."] = "HR फ़ाइलों में व्यक्तिगत डेटा होता है. इन्हें ई-मेल से आगे न भेजें और असुरक्षित फ़ोल्डरों में कॉपी न छोड़ें.",
|
||||||
|
["Neue Auswertungen im Cockpit"] = "कॉकपिट में नई दृश्यावलियां",
|
||||||
|
["Managementsicht anonymisiert Personendaten fuer Fuehrungsberichte."] = "प्रबंधन दृश्य रिपोर्टों के लिए व्यक्तिगत डेटा को अनाम करता है.",
|
||||||
|
["Dateistatus zeigt Pfad, Zeilen, Aenderungsdatum, Alter und Frische."] = "फ़ाइल स्थिति पथ, पंक्तियां, संशोधन तिथि, आयु और ताजगी दिखाती है.",
|
||||||
|
["HR-Ampel fasst Fluktuation, Krankheit, GLZ, Restferien und Datenqualitaet zusammen."] = "HR स्थिति टर्नओवर, बीमारी, समय शेष, छुट्टी शेष और डेटा गुणवत्ता को सारांशित करती है.",
|
||||||
|
["GLZ- und Restferien-Ampeln koennen gefiltert werden."] = "समय शेष और छुट्टी शेष स्थितियों को फ़िल्टर किया जा सकता है.",
|
||||||
|
["Periodenvergleich zeigt die wichtigsten Vorjahreswerte, soweit Daten vorhanden sind."] = "अवधि तुलना उपलब्ध डेटा के अनुसार पिछले वर्ष के मुख्य मान दिखाती है.",
|
||||||
|
["Datenqualitaet markiert fehlende Dateien, alte Dateien und auffaellige Werte."] = "डेटा गुणवत्ता गुम फ़ाइलें, पुरानी फ़ाइलें और असामान्य मान चिह्नित करती है.",
|
||||||
|
["Austritte werden nach Austrittsart und Organisation gruppiert."] = "निकासों को निकास प्रकार और संगठन के अनुसार समूहित किया जाता है.",
|
||||||
|
["Absenzen werden nach Organisation ausgewertet."] = "अनुपस्थितियों का मूल्यांकन संगठन के अनुसार किया जाता है.",
|
||||||
|
["Top-Absenzen und kritische Detailtabellen helfen bei der operativen Pruefung."] = "शीर्ष अनुपस्थितियां और महत्वपूर्ण विवरण तालिकाएं संचालन जांच में मदद करती हैं.",
|
||||||
|
["Drucken/PDF erzeugt eine weitergebbare Ansicht aus dem Browser."] = "प्रिंट/PDF ब्राउज़र से साझा करने योग्य दृश्य बनाता है.",
|
||||||
|
["Erwartete Dateien"] = "अपेक्षित फ़ाइलें",
|
||||||
|
["Inhalt"] = "सामग्री",
|
||||||
|
["Datei/Pfad"] = "फ़ाइल/पथ",
|
||||||
|
["gefunden"] = "मिला",
|
||||||
|
["fehlt"] = "गुम",
|
||||||
|
["Source Viewer"] = "स्रोत दर्शक",
|
||||||
|
["Zurueck zur Transformation"] = "रूपांतरण पर वापस",
|
||||||
|
["Datei:"] = "फ़ाइल:",
|
||||||
|
["Klasse:"] = "क्लास:",
|
||||||
|
["bei Zeile"] = "पंक्ति पर",
|
||||||
|
["Kein Dateipfad angegeben."] = "कोई फ़ाइल पथ नहीं दिया गया.",
|
||||||
|
["Ungueltiger Dateipfad."] = "अमान्य फ़ाइल पथ.",
|
||||||
|
["Transformer Ansicht"] = "रूपांतरण दृश्य",
|
||||||
|
["Transformationscode"] = "रूपांतरण कोड",
|
||||||
|
["Keine Beschreibung."] = "कोई विवरण नहीं.",
|
||||||
|
["Optionales Argument."] = "वैकल्पिक तर्क."
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public string CurrentLanguage => _currentLanguage;
|
public string CurrentLanguage => _currentLanguage;
|
||||||
|
|
||||||
@@ -18,7 +634,7 @@ public sealed class UiTextService : IUiTextService
|
|||||||
|
|
||||||
public void SetLanguage(string language)
|
public void SetLanguage(string language)
|
||||||
{
|
{
|
||||||
var normalized = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase) ? "en" : "de";
|
var normalized = NormalizeLanguage(language);
|
||||||
if (string.Equals(_currentLanguage, normalized, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(_currentLanguage, normalized, StringComparison.OrdinalIgnoreCase))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -27,5 +643,23 @@ public sealed class UiTextService : IUiTextService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public string Text(string german, string english)
|
public string Text(string german, string english)
|
||||||
=> string.Equals(_currentLanguage, "en", StringComparison.OrdinalIgnoreCase) ? english : german;
|
{
|
||||||
|
if (string.Equals(_currentLanguage, "de", StringComparison.OrdinalIgnoreCase))
|
||||||
|
return german;
|
||||||
|
if (string.Equals(_currentLanguage, "en", StringComparison.OrdinalIgnoreCase))
|
||||||
|
return english;
|
||||||
|
|
||||||
|
return Translations.TryGetValue(_currentLanguage, out var languageTranslations) &&
|
||||||
|
languageTranslations.TryGetValue(german, out var translated)
|
||||||
|
? translated
|
||||||
|
: english;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizeLanguage(string language)
|
||||||
|
{
|
||||||
|
var normalized = (language ?? string.Empty).Trim().ToLowerInvariant();
|
||||||
|
if (normalized is "in" or "ind" or "india" or "hindi")
|
||||||
|
normalized = "hi";
|
||||||
|
return SupportedLanguages.Contains(normalized) ? normalized : "de";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,17 @@ public class ExcelExportServiceTests
|
|||||||
|
|
||||||
Assert.Equal(2, includedGermanyRows.Count);
|
Assert.Equal(2, includedGermanyRows.Count);
|
||||||
Assert.Equal(80m, includedGermanyRows.Sum(row => row.Cell(39).GetValue<decimal>()));
|
Assert.Equal(80m, includedGermanyRows.Sum(row => row.Cell(39).GetValue<decimal>()));
|
||||||
|
|
||||||
|
var details = workbook.Worksheet("Finance Details");
|
||||||
|
var includedGermanyDetailRows = details.RowsUsed()
|
||||||
|
.Where(row => row.RowNumber() > 4)
|
||||||
|
.Where(row => row.Cell(1).GetValue<int>() == 2025)
|
||||||
|
.Where(row => row.Cell(2).GetString() == "DE")
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
Assert.Equal(2, includedGermanyDetailRows.Count);
|
||||||
|
Assert.Equal(80m, includedGermanyDetailRows.Sum(row => row.Cell(5).GetValue<decimal>()));
|
||||||
|
Assert.All(includedGermanyDetailRows, row => Assert.Equal("Sales Price/Value", row.Cell(6).GetString()));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public class ManualExcelDataSourceAdapterTests
|
|||||||
|
|
||||||
public string LastResolvedTsc { get; private set; } = string.Empty;
|
public string LastResolvedTsc { get; private set; } = string.Empty;
|
||||||
|
|
||||||
public Task UploadAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string exportFolder, string land, string localFilePath)
|
public Task UploadAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string exportFolder, string land, string localFilePath, bool uploadTimestampedCopyIfLocked = false)
|
||||||
=> Task.CompletedTask;
|
=> Task.CompletedTask;
|
||||||
|
|
||||||
public Task<string> DownloadToTempFileAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string fileReference)
|
public Task<string> DownloadToTempFileAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string fileReference)
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using TrafagSalesExporter.Services;
|
||||||
|
|
||||||
|
namespace TrafagSalesExporter.Tests;
|
||||||
|
|
||||||
|
public class UiTextServiceTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Text_Returns_Selected_Language_Or_English_Fallback()
|
||||||
|
{
|
||||||
|
var service = new UiTextService();
|
||||||
|
|
||||||
|
Assert.Equal("Standorte", service.Text("Standorte", "Sites"));
|
||||||
|
|
||||||
|
service.SetLanguage("en");
|
||||||
|
Assert.Equal("Sites", service.Text("Standorte", "Sites"));
|
||||||
|
|
||||||
|
service.SetLanguage("es");
|
||||||
|
Assert.Equal("Sitios", service.Text("Standorte", "Sites"));
|
||||||
|
|
||||||
|
service.SetLanguage("it");
|
||||||
|
Assert.Equal("Sedi", service.Text("Standorte", "Sites"));
|
||||||
|
|
||||||
|
service.SetLanguage("hi");
|
||||||
|
Assert.Equal("साइटें", service.Text("Standorte", "Sites"));
|
||||||
|
Assert.Equal("Untranslated English", service.Text("Nicht uebersetzt", "Untranslated English"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,3 +12,21 @@ html, body {
|
|||||||
width: auto;
|
width: auto;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.language-menu {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.language-button {
|
||||||
|
min-width: 84px;
|
||||||
|
height: 34px;
|
||||||
|
border-color: rgba(255, 255, 255, 0.65) !important;
|
||||||
|
color: #fff !important;
|
||||||
|
text-transform: none;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.language-button .mud-button-icon-start,
|
||||||
|
.language-button .mud-button-icon-end {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user