86 lines
5.2 KiB
C#
86 lines
5.2 KiB
C#
using System.Globalization;
|
|
using LehrerApp.Core.Models;
|
|
using LehrerApp.Core.Services;
|
|
using LehrerApp.Desktop.ViewModels.Groups;
|
|
using LehrerApp.Templating;
|
|
|
|
namespace LehrerApp.Desktop.Services;
|
|
|
|
/// <summary>Platzhalterwerte für Klausur-Deckblätter (Vorlagen mit
|
|
/// <c>report-type=exam-cover</c>): die Standardwerte der Elternbriefe (Student.*, Group.Name, …)
|
|
/// plus Exam.*, Result.* und die Punktetabelle. Alle Punktwerte gelten für die Fassung, die der
|
|
/// Schüler geschrieben hat.</summary>
|
|
public static class ExamCoverPlaceholderBuilder
|
|
{
|
|
/// <summary>Stehen statt Punkten bzw. Note auf dem Blatt, solange nichts eingetragen wird —
|
|
/// als Linie zum Ausfüllen von Hand.</summary>
|
|
public const string BlankPoints = "_________", BlankGrade = "_____";
|
|
|
|
private static readonly CultureInfo German = CultureInfo.GetCultureInfo("de-DE");
|
|
|
|
/// <param name="result">Ergebnis des Schülers oder null. Punkte und Note werden nur
|
|
/// eingetragen, wenn <paramref name="fillResults"/> gesetzt und das Ergebnis korrigiert ist.</param>
|
|
/// <param name="studentNiveau">Niveau des Schülers in dieser Lerngruppe, falls die Arbeit
|
|
/// selbst keinem Niveau zugeordnet ist.</param>
|
|
/// <param name="title">Titel für das Deckblatt, falls er vom internen Klausurtitel abweichen
|
|
/// soll; null oder leer nimmt den Klausurtitel.</param>
|
|
public static Dictionary<string, PlaceholderValue> Build(Exam exam, LearningGroup group, string subjectName,
|
|
Student student, ExamResult? result, bool fillResults, GradingService grading, LoadedTemplate template,
|
|
DateOnly today, Niveau? studentNiveau = null, string teacherAbbreviation = "",
|
|
string? title = null, Exam? original = null, ExamResult? originalResult = null,
|
|
InterimGrade? interim = null)
|
|
{
|
|
var tasks = exam.Tasks.OrderBy(t => t.Nr).ToList();
|
|
var variant = result?.Variant ?? ExamVariant.A;
|
|
var maximum = ExamScoringService.Maximum(tasks, variant);
|
|
var filled = fillResults && ExamCoverSheetService.IsCorrected(result);
|
|
|
|
var values = LetterPlaceholderBuilder.BuildStandardValues(student, contact: null, group, today, "", "");
|
|
values["Group.GradeLevel"] = new TextValue(group.GradeLevel > 0 ? group.GradeLevel.ToString() : "");
|
|
values["Subject.Name"] = new TextValue(subjectName);
|
|
values["Exam.Title"] = new TextValue(string.IsNullOrWhiteSpace(title) ? exam.Title : title.Trim());
|
|
values["Exam.Date"] = new DateValue(exam.Date);
|
|
values["Exam.Number"] = new TextValue(exam.ExamNumber?.ToString() ?? "");
|
|
values["Exam.Kind"] = new TextValue(exam.Kind.Label());
|
|
values["Exam.Niveau"] = new TextValue(exam.Niveau.HasValue ? NiveauDisplay.ToName(exam.Niveau) : "");
|
|
values["Exam.Course"] = new TextValue(CourseLabel(group, exam.Niveau ?? studentNiveau));
|
|
values["Teacher.Abbreviation"] = new TextValue(teacherAbbreviation.Trim());
|
|
values["Exam.Variant"] = new TextValue(tasks.Any(t => t.Variant is not null) ? variant.ToString() : "");
|
|
values["Exam.MaxPoints"] = new TextValue(Format(maximum));
|
|
values["Exam.ApprovalDate"] = new TextValue(Format(exam.ApprovalGrantedAt));
|
|
values["Exam.AnnouncedDate"] = new TextValue(Format(exam.AnnouncedAt));
|
|
values["Exam.ReturnDate"] = new TextValue(Format(exam.ReturnedAt));
|
|
values["Result.Points"] = new TextValue(filled ? Format(result!.TotalPoints) : BlankPoints);
|
|
values["Result.Percent"] = new TextValue(filled && maximum > 0
|
|
? (result!.TotalPoints / maximum).ToString("0 %", German) : "");
|
|
values["Result.Grade"] = new TextValue(filled
|
|
? result!.Grade ?? grading.CalculateGrade(result.TotalPoints, maximum, exam.GradingKey) : BlankGrade);
|
|
|
|
// Ohne Box in der Vorlage gibt es nichts zu zeichnen (die Tabelle ist optional).
|
|
values[ExamPointsTableDrawingBuilder.PlaceholderName] =
|
|
LetterPlaceholderBuilder.FindDeclaredDrawingBox(template, ExamPointsTableDrawingBuilder.PlaceholderName) is { } box
|
|
? ExamPointsTableDrawingBuilder.Build(
|
|
ExamCoverSheetService.Columns(tasks, variant, filled ? result!.Points : null),
|
|
box.Width, box.MillimeterScale)
|
|
: new DrawingValue([], 0);
|
|
values[ReportTextDrawing.RepeatInfo] = DrawingBoxLocator.Find(template, ReportTextDrawing.RepeatInfo) is null
|
|
? new DrawingValue([], 0) : GradeReportDrawingBuilder.Repeat(exam, original, originalResult, template);
|
|
values[ReportTextDrawing.InterimGrades] = interim is null
|
|
? new DrawingValue([], 0) : GradeReportDrawingBuilder.Interim(interim, template);
|
|
return values;
|
|
}
|
|
|
|
/// <summary>"E-Kurs" / "G-Kurs" für die äußere Differenzierung; leer im Klassenverband und
|
|
/// ohne E-/G-Zuordnung.</summary>
|
|
public static string CourseLabel(LearningGroup group, Niveau? niveau) =>
|
|
group.Type == GroupType.Class ? "" : niveau switch
|
|
{
|
|
Niveau.E => "E-Kurs",
|
|
Niveau.G => "G-Kurs",
|
|
_ => "",
|
|
};
|
|
|
|
private static string Format(double value) => value.ToString("0.##", German);
|
|
private static string Format(DateOnly? date) => date?.ToString("dd.MM.yyyy", CultureInfo.InvariantCulture) ?? "";
|
|
}
|