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

de.svws_nrw.data.stundenplan.DataStundenplanKlassen 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.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import de.svws_nrw.core.data.stundenplan.StundenplanKlasse;
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.schueler.DTOSchuelerLernabschnittsdaten;
import de.svws_nrw.db.dto.current.schild.schule.DTOJahrgang;
import de.svws_nrw.db.dto.current.schild.stundenplan.DTOStundenplan;
import de.svws_nrw.db.dto.current.schild.stundenplan.DTOStundenplanUnterrichtKlasse;
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 StundenplanKlasse}.
 */
public final class DataStundenplanKlassen extends DataManager {

	private final Long stundenplanID;

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


	/**
	 * Lambda-Ausdruck zum Umwandeln eines Datenbank-DTOs {@link DTOKlassen} in
	 * einen Core-DTO {@link StundenplanKlasse}.
	 */
	private static final Function dtoMapper = (final DTOKlassen k) -> {
		final StundenplanKlasse daten = new StundenplanKlasse();
		daten.id = k.ID;
		daten.kuerzel = k.Klasse;
		daten.bezeichnung = (k.Bezeichnung == null) ? "" : k.Bezeichnung;
		daten.sortierung = (k.Sortierung == null) ? 32000 : k.Sortierung;
		daten.istSichtbar = k.Sichtbar;
		return daten;
	};


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


	/**
	 * Gibt die Klassen des Stundenplans zurück.
	 *
	 * @param conn            die Datenbankverbindung
	 * @param idStundenplan   die ID des Stundenplans
	 *
	 * @return die Liste der Klassen
	 *
	 * @throws ApiOperationException im Fehlerfall
	 */
	public static List getKlassen(final @NotNull DBEntityManager conn, final long idStundenplan) throws ApiOperationException {
		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));
		final List klassen = conn.queryList(DTOKlassen.QUERY_BY_SCHULJAHRESABSCHNITTS_ID, DTOKlassen.class, stundenplan.Schuljahresabschnitts_ID);
		if (klassen.isEmpty())
			return new ArrayList<>();
		final List klassenIDs = klassen.stream().map(k -> k.ID).toList();
		final List jahrgaengsIDs = DataStundenplanJahrgaenge.getJahrgaenge(conn, idStundenplan).stream().map(j -> j.id).toList();
		// Bestimme die Schüler-Lernabschnitte für die Zuordnung der Schüler zu den Klassen
		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, idStundenplan, klassenIDs);
		final Map> mapKlasseSchuelerIDs = lernabschnitte.stream()
				.collect(Collectors.groupingBy(la -> la.Klassen_ID, Collectors.mapping(la -> la.Schueler_ID, Collectors.toList())));
		// Erstelle die Core-DTOs
		final ArrayList daten = new ArrayList<>();
		for (final DTOKlassen k : klassen) {
			final StundenplanKlasse klasse = dtoMapper.apply(k);
			if (k.Jahrgang_ID == null) {
				klasse.jahrgaenge.addAll(jahrgaengsIDs);
			} else {
				klasse.jahrgaenge.add(k.Jahrgang_ID);
			}
			final List schuelerIDs = mapKlasseSchuelerIDs.get(klasse.id);
			if ((schuelerIDs != null) && (!schuelerIDs.isEmpty()))
				klasse.schueler.addAll(schuelerIDs);
			daten.add(klasse);
		}
		return daten;
	}


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

	/**
	 * Ermittelt die Informationen zu der angegebenen Klasse für den angegebenen Stundenplan.
	 *
	 * @param conn             die Datenbank-Verbindung
	 * @param idStundenplan    die ID des Stundenplans
	 * @param idKlasse         die ID der Klasse
	 *
	 * @return die Informationen zu der angegebenen Klasse für den angegebenen Stundenplan
	 *
	 * @throws ApiOperationException im Fehlerfall
	 */
	public static StundenplanKlasse getById(final DBEntityManager conn, final long idStundenplan, final long idKlasse) throws ApiOperationException {
		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));
		final DTOKlassen klasse = conn.queryByKey(DTOKlassen.class, idKlasse);
		if (klasse == null)
			throw new ApiOperationException(Status.NOT_FOUND, "Es wurde keine Klasse mit der ID %d gefunden.".formatted(idKlasse));
		if (klasse.Schuljahresabschnitts_ID != stundenplan.Schuljahresabschnitts_ID)
			throw new ApiOperationException(Status.BAD_REQUEST,
					"Der Schuljahresabschnitt %d der Klasse mit der ID %d stimmt nicht mit dem Schuljahresabschitt %d bei dem Stundenplan mit der ID %d überein."
							.formatted(klasse.Schuljahresabschnitts_ID, klasse.ID, stundenplan.Schuljahresabschnitts_ID, stundenplan.ID));
		// Jahrgänge bestimmen
		final List jahrgangsIDs = new ArrayList<>();
		if (klasse.Jahrgang_ID == null) {
			jahrgangsIDs.addAll(conn.queryAll(DTOJahrgang.class).stream().map(j -> j.ID).toList());
		} else {
			jahrgangsIDs.add(klasse.Jahrgang_ID);
		}
		// Bestimme die Schüler-Lernabschnitte für die Zuordnung der Schüler zu den Klassen
		final List lernabschnitte = conn.queryList(
				"SELECT e FROM DTOSchuelerLernabschnittsdaten e WHERE e.Schuljahresabschnitts_ID = ?1 AND e.Klassen_ID = ?2 AND e.WechselNr = 0",
				DTOSchuelerLernabschnittsdaten.class, idStundenplan, klasse.ID);
		final List schuelerIDs = lernabschnitte.stream().map(la -> la.Schueler_ID).distinct().toList();
		// DTO erstellen
		final StundenplanKlasse daten = dtoMapper.apply(klasse);
		daten.jahrgaenge.addAll(jahrgangsIDs);
		daten.schueler.addAll(schuelerIDs);
		return daten;
	}

	@Override
	public Response get(final Long id) throws ApiOperationException {
		if (id == null)
			throw new ApiOperationException(Status.BAD_REQUEST, "Eine Anfrage zu einer Klasse mit der ID null ist unzulässig.");
		final StundenplanKlasse daten = getById(conn, stundenplanID, 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();
	}

	/**
	 * Erstellt eine Map, in der Klassen den gegebenen UnterrichtIds eines
	 * Stundenplans zugeordnet werden.
	 *
	 * @param conn            die Datenbankverbindung
	 * @param idStundenplan   die ID des Stundenplans
	 * @param unterrichtIds   die unterrichte, denen die Klassen zugeordnet werden sollen
	 *
	 * @return eine Map, in der allen UnterrichtsIds die Klassen zugeordnet werden
	 *
	 * @throws ApiOperationException im Fehlerfall
	 */
	public static Map> getKlassenByUnterrichtIds(final DBEntityManager conn,
			final Long idStundenplan, final List unterrichtIds) throws ApiOperationException {
		final Map> result = new HashMap<>();
		if (unterrichtIds == null)
			throw new ApiOperationException(Status.NOT_FOUND, "Keine Unterricht-IDs gegeben.");
		if (unterrichtIds.isEmpty())
			return result;
		final List klassen = DataStundenplanKlassen.getKlassen(conn, idStundenplan);
		if (klassen.isEmpty())
			return result;
		final Map klasseById = klassen.stream().collect(Collectors.toMap(k -> k.id, Function.identity()));
		final List unterrichtKlassen = conn.queryList(
				DTOStundenplanUnterrichtKlasse.QUERY_LIST_BY_UNTERRICHT_ID, DTOStundenplanUnterrichtKlasse.class, unterrichtIds);
		List klassenByUnterrichtId;
		for (final DTOStundenplanUnterrichtKlasse unterrichtKlasse : unterrichtKlassen) {
			klassenByUnterrichtId = result.computeIfAbsent(unterrichtKlasse.Unterricht_ID, unterrichtId -> new ArrayList<>());
			klassenByUnterrichtId.add(klasseById.get(unterrichtKlasse.Klasse_ID));
		}
		return result;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy