All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.svws_nrw.data.stundenplan.DataStundenplanSchueler Maven / Gradle / Ivy

Go to download

Diese Bibliothek unterstützt bei dem Zugriff auf Datenbanken für die Schulverwaltungssoftware in NRW

There is a newer version: 1.0.1
Show newest version
package de.svws_nrw.data.stundenplan;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import de.svws_nrw.core.data.stundenplan.StundenplanSchueler;
import de.svws_nrw.data.DataManager;
import de.svws_nrw.db.DBEntityManager;
import de.svws_nrw.db.dto.current.schild.klassen.DTOKlassen;
import de.svws_nrw.db.dto.current.schild.kurse.DTOKurs;
import de.svws_nrw.db.dto.current.schild.kurse.DTOKursSchueler;
import de.svws_nrw.db.dto.current.schild.schueler.DTOSchueler;
import de.svws_nrw.db.dto.current.schild.schueler.DTOSchuelerLernabschnittsdaten;
import de.svws_nrw.db.dto.current.schild.schule.DTOEigeneSchule;
import de.svws_nrw.db.dto.current.schild.stundenplan.DTOStundenplan;
import de.svws_nrw.db.utils.ApiOperationException;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;

/**
 * Diese Klasse erweitert den abstrakten {@link DataManager} für den
 * Core-DTO {@link StundenplanSchueler}.
 */
public final class DataStundenplanSchueler extends DataManager {

	private final Long stundenplanID;

	/**
	 * Erstellt einen neuen {@link DataManager} für den Core-DTO {@link StundenplanSchueler}.
	 *
	 * @param conn            die Datenbank-Verbindung für den Datenbankzugriff
	 * @param stundenplanID   die ID des Stundenplans, dessen Schüler abgefragt werden
	 */
	public DataStundenplanSchueler(final DBEntityManager conn, final Long stundenplanID) {
		super(conn);
		this.stundenplanID = stundenplanID;
	}


	/**
	 * Lambda-Ausdruck zum Umwandeln eines Datenbank-DTOs {@link DTOSchueler} in einen Core-DTO {@link StundenplanSchueler}.
	 */
	public static final Function dtoMapper = (final DTOSchueler s) -> {
		final StundenplanSchueler daten = new StundenplanSchueler();
		daten.id = s.ID;
		daten.nachname = s.Nachname;
		daten.vorname = s.Vorname;
		return daten;
	};



	@Override
	public Response getAll() throws ApiOperationException {
		return this.getList();
	}

	/**
	 * Gibt die Schüler, die im Stundenplan vorkommen, zurück.
	 *
	 * @param conn            die Datenbankverbindung
	 * @param idStundenplan   die ID des Stundenplans
	 *
	 * @return die Liste der Schüler
	 *
	 * @throws ApiOperationException im Fehlerfall
	 */
	public static List getSchueler(final @NotNull DBEntityManager conn, final long idStundenplan) throws ApiOperationException {
		final DTOEigeneSchule schule = conn.querySingle(DTOEigeneSchule.class);
		if (schule == null)
			throw new ApiOperationException(Status.NOT_FOUND);
		final DTOStundenplan stundenplan = conn.queryByKey(DTOStundenplan.class, idStundenplan);
		if (stundenplan == null)
			throw new ApiOperationException(Status.NOT_FOUND, "Es wurde kein Stundenplan mit der ID %d gefunden.".formatted(idStundenplan));
		// Bestimme alle Klassen-IDs der Schuljahresabschnitts
		final List klassenIDs = conn.queryList(DTOKlassen.QUERY_BY_SCHULJAHRESABSCHNITTS_ID, DTOKlassen.class, stundenplan.Schuljahresabschnitts_ID)
				.stream().map(k -> k.ID).toList();
		// Bestimme alle Schüler-IDs von SchuelerLernabschnittsdaten, wo die Klasse zugeordnet ist und der Schuljahresabschnitt übereinstimmt
		final Set schuelerIDs = new HashSet<>();
		final Map mapSchuelerKlasse = new HashMap<>();
		if (!klassenIDs.isEmpty()) {
			final List lernabschnitte = conn.queryList(
					"SELECT e FROM DTOSchuelerLernabschnittsdaten e WHERE e.Schuljahresabschnitts_ID = ?1 AND e.Klassen_ID IN ?2 AND e.WechselNr = 0",
					DTOSchuelerLernabschnittsdaten.class, stundenplan.Schuljahresabschnitts_ID, klassenIDs);
			mapSchuelerKlasse.putAll(lernabschnitte.stream().collect(Collectors.toMap(l -> l.Schueler_ID, l -> l.Klassen_ID)));
			schuelerIDs.addAll(lernabschnitte.stream().map(l -> l.Schueler_ID).toList());
		}
		// Bestimme alle Kurs-IDs der Unterrichte
		final List kursIDs = conn.queryList(DTOKurs.QUERY_BY_SCHULJAHRESABSCHNITTS_ID, DTOKurs.class, stundenplan.Schuljahresabschnitts_ID)
				.stream().map(k -> k.ID).toList();
		if (!kursIDs.isEmpty()) {
			final List kursSchuelerIDs = conn.queryList(
					"SELECT e FROM DTOKursSchueler e WHERE e.Kurs_ID IN ?1 AND e.LernabschnittWechselNr = 0", DTOKursSchueler.class, kursIDs).stream()
					.map(ks -> ks.Schueler_ID).distinct().toList();
			schuelerIDs.addAll(kursSchuelerIDs);
		}
		// Und bestimme nun die Schüler-Daten...
		final List schuelerListe = conn.queryByKeyList(DTOSchueler.class, schuelerIDs);
		final ArrayList daten = new ArrayList<>();
		for (final DTOSchueler s : schuelerListe) {
			// TODO Filtere alle Schüler, die ein Abgangsdatum haben, welches vor dem Beginn des Stundenplans liegt
			final Long idKlasse = mapSchuelerKlasse.get(s.ID);
			if (idKlasse == null)
				throw new ApiOperationException(Status.INTERNAL_SERVER_ERROR,
						"Für den Schüler mit der ID %d konnte keine Klassen-ID ermittelt werden.".formatted(s.ID));
			final StundenplanSchueler schueler = dtoMapper.apply(s);
			schueler.idKlasse = idKlasse;
			daten.add(schueler);
		}
		return daten;
	}


	@Override
	public Response getList() throws ApiOperationException {
		final List daten = getSchueler(conn, this.stundenplanID);
		return Response.status(Status.OK).type(MediaType.APPLICATION_JSON).entity(daten).build();
	}


	@Override
	public Response get(final Long id) throws ApiOperationException {
		final DTOStundenplan stundenplan = conn.queryByKey(DTOStundenplan.class, stundenplanID);
		if (stundenplan == null)
			throw new ApiOperationException(Status.NOT_FOUND, "Es wurde kein Stundenplan mit der ID %d gefunden.".formatted(stundenplanID));
		if (id == null)
			throw new ApiOperationException(Status.BAD_REQUEST, "Eine Anfrage zu einem Schüler mit der ID null ist unzulässig.");
		final DTOSchueler schueler = conn.queryByKey(DTOSchueler.class, id);
		if (schueler == null)
			throw new ApiOperationException(Status.NOT_FOUND, "Es wurde kein Schüler mit der ID %d gefunden.".formatted(id));
		final List abschnitte = conn.queryList(
				"SELECT e FROM DTOSchuelerLernabschnittsdaten e WHERE e.Schueler_ID = ?1 AND e.Schuljahresabschnitts_ID = ?2 AND e.WechselNr = 0",
				DTOSchuelerLernabschnittsdaten.class, id, stundenplan.Schuljahresabschnitts_ID);
		if (abschnitte.size() != 1)
			throw new ApiOperationException(Status.NOT_FOUND, "Der Schüler mit der ID %d hat keinen oder mehr als einen Lernabschnitt.".formatted(id));
		final DTOSchuelerLernabschnittsdaten abschnitt = abschnitte.get(0);
		final StundenplanSchueler daten = dtoMapper.apply(schueler);
		daten.idKlasse = abschnitt.Klassen_ID;
		return Response.status(Status.OK).type(MediaType.APPLICATION_JSON).entity(daten).build();
	}


	@Override
	public Response patch(final Long id, final InputStream is) {
		throw new UnsupportedOperationException();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy