@page "/transformations" @using Microsoft.EntityFrameworkCore @using System.Reflection @using TrafagSalesExporter.Data @using TrafagSalesExporter.Models @using TrafagSalesExporter.Services @inject IDbContextFactory DbFactory @inject ITransformationCatalog TransformationCatalog @inject ISnackbar Snackbar @inject IUiTextService UiText @T("Transformationen", "Transformations") @T("Transformer Ansicht", "Transformation view") @T("Definiere pro Quellsystem einfache Feldregeln und komplexe record-basierte Strategien.", "Define simple field rules and complex record-based strategies per source system.") `Value`-Regeln arbeiten feldweise. `Record`-Regeln rufen eine registrierte C#-Strategie auf und koennen mehrere Felder eines Datensatzes verwenden. @T("Regel hinzufuegen", "Add rule") @T("Alle speichern", "Save all") Aktiv System Scope Source Target Typ / Klasse Argument Sort Info Aktionen @foreach (var system in _systems) { @system } @foreach (var scope in _ruleScopes) { @scope } @if (IsRecordScope(context)) { } else { @foreach (var field in _recordFields) { @field } } @foreach (var field in _recordFields) { @field } @{ var availableTypes = GetTypesForScope(context.RuleScope); } @foreach (var type in availableTypes) { @(IsRecordScope(context) ? $"Klasse: {type.Key}" : type.Key) } @if (IsRecordScope(context)) { Hier waehlt man die registrierte C#-Strategie. } @{ var catalogItem = GetCatalogItem(context); } @((catalogItem?.Description ?? T("Keine Beschreibung.", "No description.")) ) @T("Code anzeigen", "Show code") @T("Transformationscode", "Transformation code") @if (_selectedCatalogItem is not null) { @_selectedCatalogItem.Key (@_selectedCatalogItem.RuleScope) @_selectedCatalogItem.Description Klasse: @_selectedCatalogItem.TypeName Datei: @_selectedCatalogItem.SourceFile Snippet
@_selectedCatalogItem.CodeSnippet
@if (_selectedRule is not null) { Aktuelle Regel System: @_selectedRule.SourceSystem Target: @_selectedRule.TargetField @if (!string.IsNullOrWhiteSpace(_selectedRule.SourceField)) { Source: @_selectedRule.SourceField } Argument: @(string.IsNullOrWhiteSpace(_selectedRule.Argument) ? "-" : _selectedRule.Argument) }
}
@T("Schliessen", "Close")
@code { private readonly string[] _systems = ["SAP", "BI1", "SAGE", "MANUAL_EXCEL"]; private readonly string[] _ruleScopes = ["Value", "Record"]; private readonly string[] _recordFields = typeof(SalesRecord) .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(p => p.Name) .OrderBy(n => n) .ToArray(); private List _rules = new(); private IReadOnlyList _catalogItems = []; private bool _codeDialogVisible; private FieldTransformationRule? _selectedRule; private TransformationCatalogItem? _selectedCatalogItem; private readonly DialogOptions _codeDialogOptions = new() { CloseButton = true, MaxWidth = MaxWidth.Medium, FullWidth = true }; protected override async Task OnInitializedAsync() { _catalogItems = TransformationCatalog.GetAll(); await LoadAsync(); } private async Task LoadAsync() { using var db = await DbFactory.CreateDbContextAsync(); _rules = await db.FieldTransformationRules.OrderBy(r => r.SortOrder).ThenBy(r => r.Id).ToListAsync(); foreach (var rule in _rules) { rule.RuleScope = string.IsNullOrWhiteSpace(rule.RuleScope) ? "Value" : rule.RuleScope; if (!GetTypesForScope(rule.RuleScope).Any(x => string.Equals(x.Key, rule.TransformationType, StringComparison.OrdinalIgnoreCase))) { rule.TransformationType = GetTypesForScope(rule.RuleScope).FirstOrDefault()?.Key ?? "Copy"; } } } private void AddRule() { var nextSort = _rules.Count == 0 ? 10 : _rules.Max(r => r.SortOrder) + 10; _rules.Add(new FieldTransformationRule { SourceSystem = "SAP", RuleScope = "Value", SourceField = nameof(SalesRecord.Material), TargetField = nameof(SalesRecord.Material), TransformationType = "Copy", SortOrder = nextSort, IsActive = true }); } private void RemoveRule(FieldTransformationRule rule) { _rules.Remove(rule); } private async Task SaveAllAsync() { using var db = await DbFactory.CreateDbContextAsync(); db.FieldTransformationRules.RemoveRange(db.FieldTransformationRules); await db.SaveChangesAsync(); db.FieldTransformationRules.AddRange(_rules); await db.SaveChangesAsync(); Snackbar.Add(T("Transformationsregeln gespeichert.", "Transformation rules saved."), Severity.Success); await LoadAsync(); } private IReadOnlyList GetTypesForScope(string? ruleScope) { var scope = string.IsNullOrWhiteSpace(ruleScope) ? "Value" : ruleScope; return TransformationCatalog.GetByScope(scope); } private static bool IsRecordScope(FieldTransformationRule rule) => string.Equals(rule.RuleScope, "Record", StringComparison.OrdinalIgnoreCase); private void ChangeRuleScope(FieldTransformationRule rule, string scope) { rule.RuleScope = scope; var firstType = GetTypesForScope(scope).FirstOrDefault()?.Key; if (!string.IsNullOrWhiteSpace(firstType)) rule.TransformationType = firstType; if (IsRecordScope(rule)) rule.SourceField = string.Empty; else if (string.IsNullOrWhiteSpace(rule.SourceField)) rule.SourceField = nameof(SalesRecord.Material); } private string GetArgumentHelperText(FieldTransformationRule rule) { var item = _catalogItems.FirstOrDefault(x => string.Equals(x.RuleScope, rule.RuleScope, StringComparison.OrdinalIgnoreCase) && string.Equals(x.Key, rule.TransformationType, StringComparison.OrdinalIgnoreCase)); return item?.Description ?? T("Optionales Argument.", "Optional argument."); } private TransformationCatalogItem? GetCatalogItem(FieldTransformationRule rule) => _catalogItems.FirstOrDefault(x => string.Equals(x.RuleScope, rule.RuleScope, StringComparison.OrdinalIgnoreCase) && string.Equals(x.Key, rule.TransformationType, StringComparison.OrdinalIgnoreCase)); private void ShowCode(FieldTransformationRule rule) { _selectedRule = rule; _selectedCatalogItem = GetCatalogItem(rule); _codeDialogVisible = _selectedCatalogItem is not null; } private void CloseCodeDialog() { _codeDialogVisible = false; _selectedRule = null; _selectedCatalogItem = null; } private static string GetSourceViewerUrl(string sourceFile, string typeName) => $"/source-viewer?path={Uri.EscapeDataString(sourceFile)}&type={Uri.EscapeDataString(typeName)}"; private static string GetTypeSelectKey(FieldTransformationRule rule) => $"{rule.Id}:{rule.RuleScope}:{rule.TransformationType}"; private string GetTypeHelperText(FieldTransformationRule rule) { var types = GetTypesForScope(rule.RuleScope); return types.Count == 0 ? T("Keine Typen fuer diesen Scope registriert.", "No types registered for this scope.") : IsRecordScope(rule) ? string.Format(T("Verfuegbare Klassen: {0}", "Available classes: {0}"), string.Join(", ", types.Select(x => x.Key))) : string.Format(T("Verfuegbare Typen: {0}", "Available types: {0}"), string.Join(", ", types.Select(x => x.Key))); } } @code { private string T(string german, string english) => UiText.Text(german, english); }