Initial
This commit is contained in:
97
LehrerApp.Core/Interfaces/IRepositories.cs
Normal file
97
LehrerApp.Core/Interfaces/IRepositories.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using LehrerApp.Core.Models;
|
||||
|
||||
namespace LehrerApp.Core.Interfaces;
|
||||
|
||||
public interface IStudentRepository
|
||||
{
|
||||
Student? GetById(Guid id);
|
||||
List<Student> GetAll(bool includeInactive = false);
|
||||
List<Student> GetByGroup(Guid groupId, string schoolYear);
|
||||
void Save(Student student);
|
||||
void Delete(Guid id);
|
||||
}
|
||||
|
||||
public interface IGroupRepository
|
||||
{
|
||||
LearningGroup? GetById(Guid id);
|
||||
List<LearningGroup> GetAll();
|
||||
List<LearningGroup> GetBySchoolYear(string schoolYear);
|
||||
void Save(LearningGroup group);
|
||||
void Delete(Guid id);
|
||||
}
|
||||
|
||||
public interface IEnrollmentRepository
|
||||
{
|
||||
List<Enrollment> GetByStudent(Guid studentId);
|
||||
List<Enrollment> GetByGroup(Guid groupId);
|
||||
List<Enrollment> GetByGroupAndYear(Guid groupId, string schoolYear);
|
||||
void Save(Enrollment enrollment);
|
||||
void Delete(Guid id);
|
||||
}
|
||||
|
||||
public interface IExamRepository
|
||||
{
|
||||
Exam? GetById(Guid id);
|
||||
List<Exam> GetByGroup(Guid groupId);
|
||||
void Save(Exam exam);
|
||||
void Delete(Guid id);
|
||||
}
|
||||
|
||||
public interface IExamResultRepository
|
||||
{
|
||||
List<ExamResult> GetByExam(Guid examId);
|
||||
List<ExamResult> GetByStudent(Guid studentId);
|
||||
ExamResult? GetByExamAndStudent(Guid examId, Guid studentId);
|
||||
void Save(ExamResult result);
|
||||
void SaveMany(List<ExamResult> results);
|
||||
}
|
||||
|
||||
public interface IGradeRepository
|
||||
{
|
||||
List<Grade> GetByStudentAndGroup(Guid studentId, Guid groupId);
|
||||
List<Grade> GetByGroup(Guid groupId);
|
||||
void Save(Grade grade);
|
||||
void Delete(Guid id);
|
||||
}
|
||||
|
||||
public interface IUnitRepository
|
||||
{
|
||||
Unit? GetById(Guid id);
|
||||
List<Unit> GetByGroup(Guid groupId);
|
||||
void Save(Unit unit);
|
||||
void Delete(Guid id);
|
||||
}
|
||||
|
||||
public interface ILessonRepository
|
||||
{
|
||||
List<Lesson> GetByUnit(Guid unitId);
|
||||
List<Lesson> GetByGroupAndDate(Guid groupId, DateOnly date);
|
||||
List<Lesson> GetByGroupAndRange(Guid groupId, DateOnly from, DateOnly to);
|
||||
void Save(Lesson lesson);
|
||||
void Delete(Guid id);
|
||||
}
|
||||
|
||||
public interface IDocumentationRepository
|
||||
{
|
||||
List<Documentation> GetByStudent(Guid studentId);
|
||||
List<Documentation> GetByStudentAndType(Guid studentId, DocumentationType type);
|
||||
void Save(Documentation doc);
|
||||
void Delete(Guid id);
|
||||
}
|
||||
|
||||
public interface IWorkTaskRepository
|
||||
{
|
||||
List<WorkTask> GetByStatus(WorkTaskStatus status);
|
||||
List<WorkTask> GetAll();
|
||||
void Save(WorkTask task);
|
||||
void Delete(Guid id);
|
||||
}
|
||||
|
||||
public interface ITimeEntryRepository
|
||||
{
|
||||
List<TimeEntry> GetByDate(DateOnly date);
|
||||
List<TimeEntry> GetByDateRange(DateOnly from, DateOnly to);
|
||||
List<TimeEntry> GetByTask(Guid taskId);
|
||||
void Save(TimeEntry entry);
|
||||
void Delete(Guid id);
|
||||
}
|
||||
8
LehrerApp.Core/LehrerApp.Core.csproj
Normal file
8
LehrerApp.Core/LehrerApp.Core.csproj
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
47
LehrerApp.Core/Models/Exam.cs
Normal file
47
LehrerApp.Core/Models/Exam.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
namespace LehrerApp.Core.Models;
|
||||
|
||||
public class Exam
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public Guid GroupId { get; set; }
|
||||
public string Title { get; set; } = ""; // "Arbeit Nr. 2 – Redox"
|
||||
public DateOnly Date { get; set; }
|
||||
public string Subject { get; set; } = "";
|
||||
public int? ExamNumber { get; set; }
|
||||
public List<ExamTask> Tasks { get; set; } = []; // nested – kein JOIN
|
||||
public List<GradingKeyEntry> GradingKey { get; set; } = [];
|
||||
public ExamStatus Status { get; set; } = ExamStatus.Planned;
|
||||
public string? Notes { get; set; }
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public class ExamTask
|
||||
{
|
||||
public int Nr { get; set; }
|
||||
public string? Title { get; set; }
|
||||
public double MaxPoints { get; set; }
|
||||
public double Weight { get; set; } = 1.0;
|
||||
}
|
||||
|
||||
public class GradingKeyEntry
|
||||
{
|
||||
public string Grade { get; set; } = ""; // "1","2"... oder "15","14"...
|
||||
public double MinPercent { get; set; }
|
||||
}
|
||||
|
||||
// Ergebnisse separat – für Notenspiegel ohne Aufgabentext laden
|
||||
public class ExamResult
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public Guid ExamId { get; set; }
|
||||
public Guid StudentId { get; set; }
|
||||
public List<double> Points { get; set; } = []; // Index = Aufgabe Nr - 1
|
||||
public double TotalPoints { get; set; }
|
||||
public string? Grade { get; set; }
|
||||
public bool Absent { get; set; }
|
||||
public string? Comment { get; set; }
|
||||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public enum ExamStatus { Planned, Conducted, Graded, Returned }
|
||||
33
LehrerApp.Core/Models/LearningGroup.cs
Normal file
33
LehrerApp.Core/Models/LearningGroup.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
namespace LehrerApp.Core.Models;
|
||||
|
||||
public class LearningGroup
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public string Name { get; set; } = ""; // "10E", "Q1 Chemie"
|
||||
public GroupType Type { get; set; }
|
||||
public string? Subject { get; set; } // "Chemie", "Mathematik"
|
||||
public string SchoolYear { get; set; } = ""; // "2024/25"
|
||||
public int GradeLevel { get; set; } // 5, 10, 11, 12 ...
|
||||
public GradingSystem GradingSystem { get; set; }
|
||||
public int? HoursPerWeek { get; set; }
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public class Enrollment
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public Guid StudentId { get; set; }
|
||||
public Guid GroupId { get; set; }
|
||||
public string SchoolYear { get; set; } = "";
|
||||
public DateOnly EnrolledAt { get; set; } = DateOnly.FromDateTime(DateTime.Today);
|
||||
public DateOnly? LeftAt { get; set; } // bei Wechsel mid-year
|
||||
}
|
||||
|
||||
public enum GroupType { Class, Course }
|
||||
|
||||
public enum GradingSystem
|
||||
{
|
||||
Grades1To6, // Noten 1–6 (Sek I)
|
||||
Points0To15, // Punkte 0–15 (Oberstufe)
|
||||
}
|
||||
57
LehrerApp.Core/Models/Planning.cs
Normal file
57
LehrerApp.Core/Models/Planning.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
namespace LehrerApp.Core.Models;
|
||||
|
||||
// ── Sonstige Noten ────────────────────────────────────────────────────────────
|
||||
|
||||
public class Grade
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public Guid StudentId { get; set; }
|
||||
public Guid GroupId { get; set; }
|
||||
public string SchoolYear { get; set; } = "";
|
||||
public GradeCategory Category { get; set; }
|
||||
public string Value { get; set; } = ""; // "2", "11", "+" je nach System
|
||||
public DateOnly Date { get; set; }
|
||||
public double Weight { get; set; } = 1.0;
|
||||
public string? Note { get; set; }
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public enum GradeCategory { Oral, Homework, Participation, Project, Other }
|
||||
|
||||
// ── Unterrichtsplanung ────────────────────────────────────────────────────────
|
||||
|
||||
public class Unit // Unterrichtseinheit / Reihe
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public Guid GroupId { get; set; }
|
||||
public string Title { get; set; } = ""; // "Ionenbindung"
|
||||
public string Subject { get; set; } = "";
|
||||
public string SchoolYear { get; set; } = "";
|
||||
public DateOnly? StartDate { get; set; }
|
||||
public DateOnly? EndDate { get; set; }
|
||||
public List<string> Competencies { get; set; } = [];
|
||||
public UnitStatus Status { get; set; } = UnitStatus.Planned;
|
||||
public string? Notes { get; set; }
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public class Lesson // Einzelstunde
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public Guid UnitId { get; set; }
|
||||
public Guid GroupId { get; set; } // Redundanz für schnelle Abfragen
|
||||
public DateOnly Date { get; set; }
|
||||
public int? LessonNumber { get; set; }
|
||||
public string Topic { get; set; } = "";
|
||||
public string? Phase { get; set; } // "Einstieg", "Erarbeitung" ...
|
||||
public List<string> Methods { get; set; } = [];
|
||||
public List<string> Materials { get; set; } = [];
|
||||
public string? Homework { get; set; }
|
||||
public string? Reflection { get; set; }
|
||||
public LessonStatus Status { get; set; } = LessonStatus.Planned;
|
||||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public enum UnitStatus { Planned, Active, Completed }
|
||||
public enum LessonStatus { Planned, Conducted }
|
||||
52
LehrerApp.Core/Models/ReadableSnapshot.cs
Normal file
52
LehrerApp.Core/Models/ReadableSnapshot.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using LehrerApp.Core.Models;
|
||||
|
||||
namespace LehrerApp.Core.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Lesbarer Snapshot der lokalen Datenbank für die WebApp.
|
||||
/// Wird periodisch vom Desktop exportiert und auf dem Server hinterlegt.
|
||||
///
|
||||
/// Bewusst NICHT enthalten:
|
||||
/// - Documentation (vertraulich, bleibt lokal)
|
||||
/// - Vollständige Notizen (nur Noten-Übersichten)
|
||||
/// - Sync-interne Daten
|
||||
/// </summary>
|
||||
public class ReadableSnapshot
|
||||
{
|
||||
public DateTime ExportedAt { get; set; } = DateTime.UtcNow;
|
||||
public string SchoolYear { get; set; } = "";
|
||||
|
||||
public List<Student> Students { get; set; } = [];
|
||||
public List<LearningGroup> Groups { get; set; } = [];
|
||||
public List<Enrollment> Enrollments { get; set; } = [];
|
||||
|
||||
// Klausuren mit Aufgaben aber ohne Ergebnisse
|
||||
public List<Exam> Exams { get; set; } = [];
|
||||
|
||||
// Ergebnisse separat – kann bei Bedarf weggelassen werden
|
||||
public List<ExamResult> ExamResults { get; set; } = [];
|
||||
|
||||
// Sonstige Noten
|
||||
public List<Grade> Grades { get; set; } = [];
|
||||
|
||||
// Unterrichtsplanung
|
||||
public List<Unit> Units { get; set; } = [];
|
||||
public List<Lesson> Lessons { get; set; } = [];
|
||||
|
||||
// Aufgaben (kein Zeiterfassungs-Detail)
|
||||
public List<WorkTask> Tasks { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Metadaten für die WebApp – wie alt ist der Snapshot?
|
||||
/// </summary>
|
||||
public SnapshotMeta Meta { get; set; } = new();
|
||||
}
|
||||
|
||||
public class SnapshotMeta
|
||||
{
|
||||
public int StudentCount { get; set; }
|
||||
public int GroupCount { get; set; }
|
||||
public int ExamCount { get; set; }
|
||||
public DateTime OldestData { get; set; }
|
||||
public string ExportedByDevice { get; set; } = "";
|
||||
}
|
||||
26
LehrerApp.Core/Models/Student.cs
Normal file
26
LehrerApp.Core/Models/Student.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
namespace LehrerApp.Core.Models;
|
||||
|
||||
public class Student
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public string FirstName { get; set; } = "";
|
||||
public string LastName { get; set; } = "";
|
||||
public string FullName => $"{LastName}, {FirstName}";
|
||||
public DateOnly? DateOfBirth { get; set; }
|
||||
public Gender? Gender { get; set; }
|
||||
public List<Contact> Contacts { get; set; } = [];
|
||||
public string? Notes { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public class Contact
|
||||
{
|
||||
public string Name { get; set; } = "";
|
||||
public string Relation { get; set; } = ""; // "Mutter", "Vater", "Vormund"
|
||||
public string? Phone { get; set; }
|
||||
public string? Email { get; set; }
|
||||
}
|
||||
|
||||
public enum Gender { M, W, D }
|
||||
70
LehrerApp.Core/Models/Workload.cs
Normal file
70
LehrerApp.Core/Models/Workload.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
namespace LehrerApp.Core.Models;
|
||||
|
||||
// ── Schülerdokumentation ──────────────────────────────────────────────────────
|
||||
|
||||
public class Documentation
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public Guid StudentId { get; set; }
|
||||
public Guid? GroupId { get; set; } // optional – nicht immer kursbezogen
|
||||
public DocumentationType Type { get; set; }
|
||||
public DateOnly Date { get; set; }
|
||||
public string Title { get; set; } = "";
|
||||
public string Content { get; set; } = "";
|
||||
public List<string> Participants { get; set; } = []; // für Gesprächsnotizen
|
||||
public AbsenceData? AbsenceData { get; set; }
|
||||
public SupportData? SupportData { get; set; }
|
||||
public bool IsConfidential { get; set; } // DSGVO: besonders schützenswert
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public class AbsenceData
|
||||
{
|
||||
public int LessonCount { get; set; }
|
||||
public bool Excused { get; set; }
|
||||
public string? Reason { get; set; }
|
||||
}
|
||||
|
||||
public class SupportData
|
||||
{
|
||||
public List<string> Measures { get; set; } = [];
|
||||
public DateOnly? ReviewDate { get; set; }
|
||||
public SupportStatus Status { get; set; } = SupportStatus.Active;
|
||||
}
|
||||
|
||||
public enum DocumentationType { Conversation, Incident, SupportPlan, Absence }
|
||||
public enum SupportStatus { Active, Completed, Paused }
|
||||
|
||||
// ── Arbeitszeit & Aufgaben ────────────────────────────────────────────────────
|
||||
|
||||
public class WorkTask
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public string Title { get; set; } = "";
|
||||
public TaskCategory Category { get; set; }
|
||||
public Guid? GroupId { get; set; }
|
||||
public DateOnly? DueDate { get; set; }
|
||||
public int? EstimatedMinutes { get; set; }
|
||||
public WorkTaskStatus Status { get; set; } = WorkTaskStatus.Open;
|
||||
public string? Notes { get; set; }
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public class TimeEntry
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public Guid? TaskId { get; set; }
|
||||
public string Category { get; set; } = "";
|
||||
public Guid? GroupId { get; set; }
|
||||
public DateOnly Date { get; set; }
|
||||
public TimeOnly? StartTime { get; set; }
|
||||
public TimeOnly? EndTime { get; set; }
|
||||
public int DurationMinutes { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public enum TaskCategory { Correction, Preparation, Admin, Meeting, Other }
|
||||
public enum WorkTaskStatus { Open, InProgress, Done }
|
||||
90
LehrerApp.Core/Services/GradingService.cs
Normal file
90
LehrerApp.Core/Services/GradingService.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using LehrerApp.Core.Models;
|
||||
|
||||
namespace LehrerApp.Core.Services;
|
||||
|
||||
public class GradingService
|
||||
{
|
||||
/// <summary>
|
||||
/// Berechnet die Note aus Punkten anhand des Notenschlüssels der Klausur.
|
||||
/// </summary>
|
||||
public string CalculateGrade(double achieved, double maximum, List<GradingKeyEntry> key)
|
||||
{
|
||||
if (maximum <= 0) return "-";
|
||||
var percent = achieved / maximum * 100.0;
|
||||
|
||||
return key
|
||||
.OrderByDescending(k => k.MinPercent)
|
||||
.FirstOrDefault(k => percent >= k.MinPercent)
|
||||
?.Grade ?? key.OrderBy(k => k.MinPercent).First().Grade;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Standardnotenschlüssel 1–6 nach NRW-Schema (anpassbar).
|
||||
/// </summary>
|
||||
public static List<GradingKeyEntry> DefaultKey1To6() =>
|
||||
[
|
||||
new() { Grade = "1", MinPercent = 87.5 },
|
||||
new() { Grade = "2", MinPercent = 75.0 },
|
||||
new() { Grade = "3", MinPercent = 62.5 },
|
||||
new() { Grade = "4", MinPercent = 50.0 },
|
||||
new() { Grade = "5", MinPercent = 25.0 },
|
||||
new() { Grade = "6", MinPercent = 0.0 },
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Standardnotenschlüssel 0–15 Punkte (Oberstufe).
|
||||
/// </summary>
|
||||
public static List<GradingKeyEntry> DefaultKey0To15() =>
|
||||
[
|
||||
new() { Grade = "15", MinPercent = 95.0 },
|
||||
new() { Grade = "14", MinPercent = 90.0 },
|
||||
new() { Grade = "13", MinPercent = 85.0 },
|
||||
new() { Grade = "12", MinPercent = 80.0 },
|
||||
new() { Grade = "11", MinPercent = 75.0 },
|
||||
new() { Grade = "10", MinPercent = 70.0 },
|
||||
new() { Grade = "9", MinPercent = 65.0 },
|
||||
new() { Grade = "8", MinPercent = 60.0 },
|
||||
new() { Grade = "7", MinPercent = 55.0 },
|
||||
new() { Grade = "6", MinPercent = 50.0 },
|
||||
new() { Grade = "5", MinPercent = 45.0 },
|
||||
new() { Grade = "4", MinPercent = 40.0 },
|
||||
new() { Grade = "3", MinPercent = 33.0 },
|
||||
new() { Grade = "2", MinPercent = 27.0 },
|
||||
new() { Grade = "1", MinPercent = 20.0 },
|
||||
new() { Grade = "0", MinPercent = 0.0 },
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Berechnet den Notendurchschnitt aus einer Liste von Notenwerten (1-6 System).
|
||||
/// </summary>
|
||||
public double AverageGrade1To6(List<string> grades)
|
||||
{
|
||||
var numeric = grades
|
||||
.Select(g => int.TryParse(g, out var n) ? (int?)n : null)
|
||||
.Where(n => n.HasValue)
|
||||
.Select(n => n!.Value)
|
||||
.ToList();
|
||||
|
||||
return numeric.Count == 0 ? 0 : numeric.Average();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Berechnet den Notendurchschnitt aus gewichteten Noten.
|
||||
/// </summary>
|
||||
public double WeightedAverage(List<(string Grade, double Weight)> grades)
|
||||
{
|
||||
var numeric = grades
|
||||
.Select(g => (
|
||||
Value: int.TryParse(g.Grade, out var n) ? (int?)n : null,
|
||||
g.Weight))
|
||||
.Where(g => g.Value.HasValue)
|
||||
.ToList();
|
||||
|
||||
if (numeric.Count == 0) return 0;
|
||||
|
||||
var totalWeight = numeric.Sum(g => g.Weight);
|
||||
var weightedSum = numeric.Sum(g => g.Value!.Value * g.Weight);
|
||||
|
||||
return totalWeight == 0 ? 0 : weightedSum / totalWeight;
|
||||
}
|
||||
}
|
||||
48
LehrerApp.Core/Services/SchoolYearService.cs
Normal file
48
LehrerApp.Core/Services/SchoolYearService.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
namespace LehrerApp.Core.Services;
|
||||
|
||||
public class SchoolYearService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gibt das aktuelle Schuljahr zurück, z.B. "2024/25".
|
||||
/// Schuljahr beginnt am 1. August.
|
||||
/// </summary>
|
||||
public string CurrentSchoolYear()
|
||||
{
|
||||
var now = DateTime.Today;
|
||||
var startYear = now.Month >= 8 ? now.Year : now.Year - 1;
|
||||
return FormatSchoolYear(startYear);
|
||||
}
|
||||
|
||||
public string FormatSchoolYear(int startYear) =>
|
||||
$"{startYear}/{(startYear + 1) % 100:D2}";
|
||||
|
||||
/// <summary>
|
||||
/// Gibt den Beginn des Schuljahres zurück (1. August).
|
||||
/// </summary>
|
||||
public DateOnly SchoolYearStart(string schoolYear)
|
||||
{
|
||||
var year = int.Parse(schoolYear.Split('/')[0]);
|
||||
return new DateOnly(year, 8, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gibt das Ende des Schuljahres zurück (31. Juli des Folgejahres).
|
||||
/// </summary>
|
||||
public DateOnly SchoolYearEnd(string schoolYear)
|
||||
{
|
||||
var year = int.Parse(schoolYear.Split('/')[0]) + 1;
|
||||
return new DateOnly(year, 7, 31);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gibt die letzten N Schuljahre zurück (für Dropdowns).
|
||||
/// </summary>
|
||||
public List<string> RecentSchoolYears(int count = 5)
|
||||
{
|
||||
var now = DateTime.Today;
|
||||
var currentStart = now.Month >= 8 ? now.Year : now.Year - 1;
|
||||
return Enumerable.Range(0, count)
|
||||
.Select(i => FormatSchoolYear(currentStart - i))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user