Files
BeWoPlaner/ReportImp/KetteReports/Export/PersonioAnwesenheitExporter.cs

87 lines
3.9 KiB
C#

using System;
using System.Linq;
using System.Text;
using BeWo.Data.Access;
using BS.Shared.Core;
using BS.Shared.DataContracts;
namespace KetteReports.Export
{
/// Exportiert die geleisteten Arbeitszeiten im Personio-Importformat "Anwesenheitsperioden" als CSV (Trennzeichen ";").
/// Quelle: ServiceRecords der Leistungskategorie "Arbeitszeit". Innerhalb dieser Kategorie gibt es die Leistungen "Arbeitszeit" und "Pause";
/// jede Buchung wird als eigene Anwesenheitsperiode exportiert.
public class PersonioAnwesenheitExporter
{
private const string Kategorie = "Arbeitszeit";
private const string Header = "E-Mail;Start (z. B. 2024-04-01 09:00);Ende (z. B. 2024-04-01 18:00);Art der Periode;Kommentar;Projekt;Unterprojekt";
public static QueryDC CreateQuery(QueryDC query)
{
var monatStart = PersonioExportUtils.GetMonthStart(query);
query.FileName = string.Format("Personio_Anwesenheitsperioden_{0:yyyyMM}.csv", monatStart);
query.QueryResult = BuildCsv(monatStart);
return query;
}
private static string BuildCsv(DateTime monatStart)
{
// Oberes Ende exklusiv: der 2-arg-DateTimeSpan-Konstruktor lässt die Uhrzeit auf 00:00,
// FindServiceRecordsInSpan verwendet Between(Start, StartDateTime, EndDateTime).
var monatEndeExklusiv = monatStart.AddMonths(1);
var identifierByEmployeeOid = PersonioExportUtils.BuildEmployeeIdentifierByOid();
var sb = new StringBuilder();
sb.Append(Header);
// Erst alle Einträge eines Mitarbeiters, innerhalb chronologisch nach Startzeitpunkt.
var serviceRecords = DAOFactory.SearchDAO.FindServiceRecordsInSpan(new DateTimeSpan(monatStart, monatEndeExklusiv), null)
.Where(sr => sr.EmployeeOid.HasValue && sr.Start.HasValue && sr.End.HasValue)
.OrderBy(sr => sr.EmployeeOid.Value).ThenBy(sr => sr.Start.Value).ToList();
foreach (var serviceRecord in serviceRecords)
{
if (!serviceRecord.EmployeeOid.HasValue || !serviceRecord.Start.HasValue || !serviceRecord.End.HasValue)
{
continue;
}
var serviceDescription = serviceRecord.ServiceDescription;
if (serviceDescription == null || serviceDescription.ServiceCategory == null)
{
continue;
}
// Nur Leistungen der Kategorie "Arbeitszeit" berücksichtigen.
var kategorieName = (serviceDescription.ServiceCategory.Name ?? string.Empty).Trim();
if (!kategorieName.Equals(Kategorie, StringComparison.OrdinalIgnoreCase))
{
continue;
}
string mitarbeiter;
identifierByEmployeeOid.TryGetValue(serviceRecord.EmployeeOid.Value, out mitarbeiter);
// Leistung "Pause" -> Art der Periode "Pause", sonst "Arbeit".
var leistung = (serviceDescription.Name ?? string.Empty).Trim();
var artDerPeriode = leistung.Equals("Pause", StringComparison.OrdinalIgnoreCase) ? "Pause" : "Arbeit";
var start = serviceRecord.Start.Value;
var end = serviceRecord.End.Value;
sb.AppendLine();
sb.Append(PersonioExportUtils.BuildCsvLine(
mitarbeiter ?? string.Empty,
start.ToString("yyyy-MM-dd HH:mm"),
end.ToString("yyyy-MM-dd HH:mm"),
artDerPeriode,
serviceRecord.Notice ?? string.Empty, // Kommentar (ServiceRecord.Notice)
string.Empty, // Projekt - nicht benötigt
string.Empty)); // Unterprojekt - nicht benötigt
}
return sb.ToString();
}
}
}