Files
BeWoPlaner/Server/Components/AICore/Context/SummaryParser/CsvContextSummaryParser.cs

196 lines
5.3 KiB
C#

using AICore.Context.Entry;
using AICore.Context.Summary;
using AICore.Context.Summary.Function;
using AICore.Context.Summary.Navigation;
using BS.Shared;
using BS.Shared.Exceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace AICore.Context.SummaryParser
{
internal class CsvContextSummaryParser : BaseContextSummaryParser
{
private string _Delimiter;
private bool _StrictEscapeCsvField;
public CsvContextSummaryParser(string delimiter = ";", bool strictEscapeCsvField = false)
{
_Delimiter = delimiter;
_StrictEscapeCsvField = strictEscapeCsvField;
}
public override string Parse(AiActionType actionType, BaseContextSummary context)
{
if (context is null)
return string.Empty;
var sb = new StringBuilder();
if (context is ServiceRecordNavigationCS summary)
{
sb.AppendLine($"<Hilfeplan>");
sb.AppendLine(summary.SupportConcept);
sb.AppendLine($"</Hilfeplan>");
sb.AppendLine();
sb.AppendLine($"<Kostenträger>");
sb.AppendLine(summary.CostBearer);
sb.AppendLine($"</Kostenträger>");
sb.AppendLine();
sb.AppendLine($"<Klient>");
sb.AppendLine(ToCsvString(summary.Customer));
sb.AppendLine($"</Klient>");
sb.AppendLine();
sb.AppendLine($"<Zeiterfassungseinträge>");
sb.AppendLine(ToCsvString(summary.ServiceRecords));
sb.AppendLine($"</Zeiterfassungseinträge>");
sb.AppendLine();
return sb.ToString();
}
else if (context is ServiceRecordDocumantationFCS fcs)
{
sb.AppendLine($"<Hilfeplan>");
sb.AppendLine(fcs.SupportConcept);
sb.AppendLine($"</Hilfeplan>");
sb.AppendLine();
sb.AppendLine($"<Kostenträger>");
sb.AppendLine(fcs.CostBearer);
sb.AppendLine($"</Kostenträger>");
sb.AppendLine();
sb.AppendLine($"<Klient>");
sb.AppendLine(ToCsvString(fcs.Customer));
sb.AppendLine($"</Klient>");
sb.AppendLine();
sb.AppendLine($"<Zeiterfassungseinträge>");
sb.AppendLine(ToCsvString(fcs.ServiceRecords));
sb.AppendLine($"</Zeiterfassungseinträge>");
sb.AppendLine();
sb.AppendLine($"<Dokumentationstext>");
sb.AppendLine(fcs.Dokutext);
sb.AppendLine($"</Dokumentationstext>");
return sb.ToString();
}
if (context.Context is IEnumerable<BaseContextEntry> values)
{
sb.AppendLine($"<Context>");
sb.AppendLine(ToCsvString(values));
sb.AppendLine($"</Context>");
return sb.ToString();
}
else if (context.Context is BaseContextEntry value)
{
sb.AppendLine($"<Context>");
sb.AppendLine(ToCsvString(value));
sb.AppendLine($"</Context>");
return sb.ToString();
}
throw BeWoNotImplementedException.CreateFromEnum(actionType);
}
public string ToCsvString(BaseContextEntry entry, bool includeHeaders = true)
{
var list = new List<BaseContextEntry>() { entry };
var csv = ToCsvString(list);
return csv;
}
/// <summary>
/// Konvertiert eine Liste von Objekten zu einem CSV-String
/// </summary>
/// <param name="objects">Liste der zu konvertierenden Objekte</param>
/// <param name="delimiter">CSV-Trennzeichen (Standard: ",")</param>
/// <param name="includeHeaders">Ob Spaltenüberschriften eingefügt werden sollen</param>
/// <returns>CSV-String</returns>
public string ToCsvString<T>(IEnumerable<T> objects, bool includeHeaders = true)
{
if (objects == null || objects.Count() == 0)
return string.Empty;
var sb = new StringBuilder();
var type = objects.First().GetType();
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
// Headers hinzufügen
if (includeHeaders)
{
for (int i = 0; i < properties.Length; i++)
{
if (i > 0) sb.Append(_Delimiter);
// Header formatieren
var name = GetJsonPropertyName(properties[i]);
sb.Append(EscapeCsvField(name));
}
sb.AppendLine();
}
// Datenzeilen hinzufügen
foreach (var obj in objects)
{
for (int i = 0; i < properties.Length; i++)
{
if (i > 0) sb.Append(_Delimiter);
var value = properties[i].GetValue(obj);
var stringValue =
value is IEnumerable<string> list
? string.Join(_Delimiter, list)
: value?.ToString() ?? string.Empty;
sb.Append(EscapeCsvField(stringValue));
}
sb.AppendLine();
}
return sb.ToString();
}
/// <summary>
/// CSV-Feld escapen (Anführungszeichen und Kommas behandeln)
/// </summary>
private string EscapeCsvField(string field)
{
if (string.IsNullOrEmpty(field))
return string.Empty;
if (_StrictEscapeCsvField)
{
return $"\"{field}\"";
}
else
{
// Wenn das Feld Kommas, Anführungszeichen oder Zeilumbrüche enthält,
// muss es in Anführungszeichen gesetzt werden
if (field.Contains(_Delimiter) || field.Contains("\"") || field.Contains("\n") || field.Contains("\r"))
{
// Anführungszeichen im Feld verdoppeln
field = field.Replace("\"", "\"\"");
return $"\"{field}\"";
}
}
return field;
}
string GetJsonPropertyName(PropertyInfo propertyInfo)
{
var jsonPropertyAttribute = propertyInfo.GetCustomAttribute<JsonPropertyNameAttribute>();
if (jsonPropertyAttribute != null)
{
return jsonPropertyAttribute.Name;
}
return propertyInfo.Name;
}
}
}