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

de.svws_nrw.data.schueler.DataSchuelerStammdaten 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.schueler;

import de.svws_nrw.core.data.schueler.SchuelerStammdaten;
import de.svws_nrw.core.exceptions.DeveloperNotificationException;
import de.svws_nrw.core.types.Geschlecht;
import de.svws_nrw.core.types.SchuelerStatus;
import de.svws_nrw.core.types.schule.Nationalitaeten;
import de.svws_nrw.core.types.schule.Verkehrssprache;
import de.svws_nrw.data.DataBasicMapper;
import de.svws_nrw.data.DataManager;
import de.svws_nrw.data.JSONMapper;
import de.svws_nrw.db.DBEntityManager;
import de.svws_nrw.db.dto.current.schild.katalog.DTOFahrschuelerart;
import de.svws_nrw.db.dto.current.schild.katalog.DTOHaltestellen;
import de.svws_nrw.db.dto.current.schild.katalog.DTOKonfession;
import de.svws_nrw.db.dto.current.schild.katalog.DTOOrtsteil;
import de.svws_nrw.db.dto.current.schild.schueler.DTOSchueler;
import de.svws_nrw.db.dto.current.schild.schueler.DTOSchuelerFoto;
import de.svws_nrw.db.schema.Schema;
import de.svws_nrw.db.utils.ApiOperationException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;

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


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

	/**
	 * Erstellt einen neuen {@link DataManager} für den Core-DTO {@link SchuelerStammdaten}.
	 *
	 * @param conn   die Datenbank-Verbindung für den Datenbankzugriff
	 */
	public DataSchuelerStammdaten(final DBEntityManager conn) {
		super(conn);
	}


	/**
	 * Lambda-Ausdruck zum Umwandeln eines Datenbank-DTOs {@link DTOSchueler} in einen Core-DTO {@link SchuelerStammdaten}.
	 */
	private static final Function dtoMapper = (final DTOSchueler schueler) -> {
		final SchuelerStammdaten daten = new SchuelerStammdaten();
		// Basisdaten
		daten.id = schueler.ID;
		daten.foto = "";
		daten.nachname = (schueler.Nachname == null) ? "" : schueler.Nachname;
		daten.vorname = (schueler.Vorname == null) ? "" : schueler.Vorname;
		daten.alleVornamen = (schueler.AlleVornamen == null) ? "" : schueler.AlleVornamen;
		daten.geschlecht = schueler.Geschlecht.id;
		daten.geburtsdatum = schueler.Geburtsdatum;
		daten.geburtsort = schueler.Geburtsort;
		daten.geburtsname = schueler.Geburtsname;
		// Wohnort und Kontaktdaten
		daten.strassenname = schueler.Strassenname;
		daten.hausnummer = schueler.HausNr;
		daten.hausnummerZusatz = schueler.HausNrZusatz;
		daten.wohnortID = schueler.Ort_ID;
		daten.ortsteilID = schueler.Ortsteil_ID;
		daten.telefon = schueler.Telefon;
		daten.telefonMobil = schueler.Fax;
		daten.emailPrivat = schueler.Email;
		daten.emailSchule = schueler.SchulEmail;
		// Daten zur Staatsangehörigkeit und zur Religion
		daten.staatsangehoerigkeitID = (schueler.StaatKrz == null) ? null : schueler.StaatKrz.daten.iso3;
		daten.staatsangehoerigkeit2ID = (schueler.StaatKrz2 == null) ? null : schueler.StaatKrz2.daten.iso3;
		daten.religionID = schueler.Religion_ID;
		daten.druckeKonfessionAufZeugnisse = schueler.KonfDruck;
		daten.religionabmeldung = schueler.Religionsabmeldung;
		daten.religionanmeldung = schueler.Religionsanmeldung;
		// Daten zum Migrationshintergrund
		// TODO DB-Converter für boolean statt Boolean beim Migrationshintergrund
		daten.hatMigrationshintergrund = (schueler.Migrationshintergrund != null) && schueler.Migrationshintergrund;
		daten.zuzugsjahr = (schueler.JahrZuzug == null) ? null : schueler.JahrZuzug;
		daten.geburtsland = (schueler.GeburtslandSchueler == null) ? null : schueler.GeburtslandSchueler.daten.iso3;
		daten.verkehrspracheFamilie = (schueler.VerkehrsspracheFamilie == null) ? null : schueler.VerkehrsspracheFamilie.daten.kuerzel;
		daten.geburtslandVater = (schueler.GeburtslandVater == null) ? null : schueler.GeburtslandVater.daten.iso3;
		daten.geburtslandMutter = (schueler.GeburtslandMutter == null) ? null : schueler.GeburtslandMutter.daten.iso3;
		// Statusdaten
		daten.status = schueler.Status.id;
		daten.istDuplikat = schueler.Duplikat;
		daten.externeSchulNr = schueler.ExterneSchulNr;
		daten.fahrschuelerArtID = schueler.Fahrschueler_ID;
		daten.haltestelleID = schueler.Haltestelle_ID;
		daten.anmeldedatum = schueler.AnmeldeDatum;
		daten.aufnahmedatum = schueler.Aufnahmedatum;
		daten.istVolljaehrig = (schueler.Volljaehrig != null) && schueler.Volljaehrig; // TODO ermittle die Information aus den anderen Schülerdaten
		daten.keineAuskunftAnDritte = schueler.KeineAuskunft;
		daten.istSchulpflichtErfuellt = (schueler.SchulpflichtErf != null) && schueler.SchulpflichtErf; // TODO ermittle die Information aus den anderen Schülerdaten
		daten.istBerufsschulpflichtErfuellt = (schueler.BerufsschulpflErf != null) && schueler.BerufsschulpflErf; // TODO ermittle die Information aus den anderen Schülerdaten
		daten.hatMasernimpfnachweis = schueler.MasernImpfnachweis;
		daten.erhaeltSchuelerBAFOEG = schueler.Bafoeg;
		daten.erhaeltMeisterBAFOEG = schueler.MeisterBafoeg;
		return daten;
	};

	@Override
	public Response getAll() {
		throw new UnsupportedOperationException();
	}

	@Override
	public Response getList() {
		throw new UnsupportedOperationException();
	}

	/**
	 * Gibt die Liste der Schülerstammdaten für die übergebenen IDs zurück.
	 *
	 * @param conn	die Datenbank-Verbindung
	 * @param ids   die Liste der Schüler-IDs
	 *
	 * @return die Liste der Schülerstammdaten
	 */
	public static List getListStammdaten(final DBEntityManager conn, final List ids) {
		if (ids == null)
			throw new DeveloperNotificationException("Die Liste darf nicht null sein.");
		final var result = new ArrayList();
		if (ids.isEmpty())
			return result;
		final List schueler = conn.queryByKeyList(DTOSchueler.class, ids);
		if ((schueler == null) || schueler.isEmpty())
			return result;
		final Map mapFotos = conn.queryByKeyList(DTOSchuelerFoto.class, ids)
				.stream().collect(Collectors.toMap(sf -> sf.Schueler_ID, sf -> sf));
		for (final DTOSchueler s : schueler) {
			final var tmp = dtoMapper.apply(s);
			final var tmpFoto = mapFotos.get(tmp.id);
			tmp.foto = (tmpFoto == null) ? null : tmpFoto.FotoBase64;
			result.add(tmp);
		}
		return result;
	}

	/**
	 * Gibt die Liste der Schülerstammdaten für die übergebene ID zurück.
	 *
	 * @param conn	die Datenbank-Verbindung
	 * @param id    die Schüler-ID
	 *
	 * @return die Liste der Schülerstammdaten
	 *
	 * @throws ApiOperationException im Fehlerfall
	 */
	public SchuelerStammdaten getStammdaten(final DBEntityManager conn, final long id) throws ApiOperationException {
		final DTOSchueler schueler = conn.queryByKey(DTOSchueler.class, id);
		if (schueler == null)
			throw new ApiOperationException(Status.NOT_FOUND);
		final SchuelerStammdaten daten = dtoMapper.apply(schueler);
		final DTOSchuelerFoto schuelerFoto = conn.queryByKey(DTOSchuelerFoto.class, id);
		if (schuelerFoto != null)
			daten.foto = schuelerFoto.FotoBase64;
		return daten;
	}

	@Override
	public Response get(final Long id) throws ApiOperationException {
		if (id == null)
			throw new ApiOperationException(Status.NOT_FOUND);
		final SchuelerStammdaten daten = getStammdaten(conn, id);
		return Response.status(Status.OK).type(MediaType.APPLICATION_JSON).entity(daten).build();
	}

	private final Map> patchMappings = Map.ofEntries(
			Map.entry("id", (conn, schueler, value, map) -> {
				final Long patch_id = JSONMapper.convertToLong(value, true);
				if ((patch_id == null) || (patch_id.longValue() != schueler.ID))
					throw new ApiOperationException(Status.BAD_REQUEST);
			}),
			Map.entry("foto", (conn, schueler, value, map) -> {
				final String strData = JSONMapper.convertToString(value, true, true, null);
				DTOSchuelerFoto schuelerFoto = conn.queryByKey(DTOSchuelerFoto.class, schueler.ID);
				if (schuelerFoto == null)
					schuelerFoto = new DTOSchuelerFoto(schueler.ID);
				final String oldFoto = schuelerFoto.FotoBase64;
				if (((strData == null) && (oldFoto == null)) || ((strData != null) && (strData.equals(oldFoto))))
					return;
				schuelerFoto.FotoBase64 = strData;
				conn.transactionPersist(schuelerFoto);
			}),
			Map.entry("nachname",
					(conn, schueler, value, map) -> schueler.Nachname =
							JSONMapper.convertToString(value, false, false, Schema.tab_Schueler.col_Name.datenlaenge())),
			Map.entry("vorname",
					(conn, schueler, value, map) -> schueler.Vorname =
							JSONMapper.convertToString(value, false, false, Schema.tab_Schueler.col_Vorname.datenlaenge())),
			Map.entry("alleVornamen",
					(conn, schueler, value, map) -> schueler.AlleVornamen =
							JSONMapper.convertToString(value, false, true, Schema.tab_Schueler.col_Zusatz.datenlaenge())),
			Map.entry("geschlecht", (conn, schueler, value, map) -> {
				final Geschlecht geschlecht = Geschlecht.fromValue(JSONMapper.convertToInteger(value, false));
				if (geschlecht == null)
					throw new ApiOperationException(Status.CONFLICT);
				schueler.Geschlecht = geschlecht;
			}),
			Map.entry("geburtsdatum", (conn, schueler, value, map) -> schueler.Geburtsdatum = JSONMapper.convertToString(value, false, false, null)),
			Map.entry("geburtsort", (conn, schueler, value, map) -> schueler.Geburtsort =
					JSONMapper.convertToString(value, true, true, Schema.tab_Schueler.col_Geburtsort.datenlaenge())),
			Map.entry("geburtsname", (conn, schueler, value, map) -> schueler.Geburtsname =
					JSONMapper.convertToString(value, true, true, Schema.tab_Schueler.col_Geburtsname.datenlaenge())),

			// Wohnort und Kontaktdaten
			Map.entry("strassenname", (conn, schueler, value, map) -> schueler.Strassenname =
					JSONMapper.convertToString(value, true, true, Schema.tab_Schueler.col_Strassenname.datenlaenge())),
			Map.entry("hausnummer", (conn, schueler, value, map) -> schueler.HausNr =
					JSONMapper.convertToString(value, true, true, Schema.tab_Schueler.col_HausNr.datenlaenge())),
			Map.entry("hausnummerZusatz", (conn, schueler, value, map) -> schueler.HausNrZusatz =
					JSONMapper.convertToString(value, true, true, Schema.tab_Schueler.col_HausNrZusatz.datenlaenge())),
			Map.entry("wohnortID", (conn, schueler, value, map) -> setWohnort(schueler, JSONMapper.convertToLong(value, true),
					(map.get("ortsteilID") == null) ? schueler.Ortsteil_ID : ((Long) map.get("ortsteilID")))),
			Map.entry("ortsteilID", (conn, schueler, value, map) -> setWohnort(schueler, (map.get("wohnortID") == null) ? schueler.Ort_ID
					: ((Long) map.get("wohnortID")), JSONMapper.convertToLong(value, true))),
			Map.entry("telefon", (conn, schueler, value, map) -> schueler.Telefon =
					JSONMapper.convertToString(value, true, true, Schema.tab_Schueler.col_Telefon.datenlaenge())),
			Map.entry("telefonMobil", (conn, schueler, value, map) -> schueler.Fax =
					JSONMapper.convertToString(value, true, true, Schema.tab_Schueler.col_Fax.datenlaenge())),
			Map.entry("emailPrivat", (conn, schueler, value, map) -> schueler.Email =
					JSONMapper.convertToString(value, true, true, Schema.tab_Schueler.col_Email.datenlaenge())),
			Map.entry("emailSchule", (conn, schueler, value, map) -> schueler.SchulEmail =
					JSONMapper.convertToString(value, true, true, Schema.tab_Schueler.col_SchulEmail.datenlaenge())),

			// Daten zur Staatsangehörigkeit und zur Religion
			Map.entry("staatsangehoerigkeitID", (conn, schueler, value, map) -> {
				final String staatsangehoerigkeitID = JSONMapper.convertToString(value, true, true, null);
				if ((staatsangehoerigkeitID == null) || ("".equals(staatsangehoerigkeitID))) {
					schueler.StaatKrz = null;
				} else {
					final Nationalitaeten nat = Nationalitaeten.getByISO3(staatsangehoerigkeitID);
					if (nat == null)
						throw new ApiOperationException(Status.NOT_FOUND);
					schueler.StaatKrz = nat;
				}
			}),
			Map.entry("staatsangehoerigkeit2ID", (conn, schueler, value, map) -> {
				final String staatsangehoerigkeit2ID = JSONMapper.convertToString(value, true, true, null);
				if ((staatsangehoerigkeit2ID == null) || ("".equals(staatsangehoerigkeit2ID))) {
					schueler.StaatKrz2 = null;
				} else {
					final Nationalitaeten nat = Nationalitaeten.getByISO3(staatsangehoerigkeit2ID);
					if (nat == null)
						throw new ApiOperationException(Status.NOT_FOUND);
					schueler.StaatKrz2 = nat;
				}
			}),
			Map.entry("religionID", (conn, schueler, value, map) -> {
				final Long religionID = JSONMapper.convertToLong(value, true);
				if (religionID != null) {
					if (religionID < 0)
						throw new ApiOperationException(Status.CONFLICT);
					final DTOKonfession rel = conn.queryByKey(DTOKonfession.class, religionID);
					if (rel == null)
						throw new ApiOperationException(Status.NOT_FOUND);
				}
				schueler.Religion_ID = religionID;
			}),
			Map.entry("druckeKonfessionAufZeugnisse", (conn, schueler, value, map) -> schueler.KonfDruck = JSONMapper.convertToBoolean(value, false)),
			Map.entry("religionabmeldung", (conn, schueler, value, map) -> schueler.Religionsabmeldung = JSONMapper.convertToString(value, true, true, null)),
			Map.entry("religionanmeldung", (conn, schueler, value, map) -> schueler.Religionsanmeldung = JSONMapper.convertToString(value, true, true, null)),

			// Daten zum Migrationshintergrund
			Map.entry("hatMigrationshintergrund", (conn, schueler, value, map) -> schueler.Migrationshintergrund = JSONMapper.convertToBoolean(value, false)),
			Map.entry("zuzugsjahr", (conn, schueler, value, map) -> {
				// TODO Bestimme das aktuelle Jahr für die obere Grenze des Bereichs
				schueler.JahrZuzug = JSONMapper.convertToIntegerInRange(value, true, 1900, 3000);
			}),
			Map.entry("geburtsland", (conn, schueler, value, map) -> {
				final String strData = JSONMapper.convertToString(value, true, true, null);
				final Nationalitaeten nat = Nationalitaeten.getByISO3(strData);
				if (nat == null)
					throw new ApiOperationException(Status.NOT_FOUND);
				schueler.GeburtslandSchueler = nat;
			}),
			Map.entry("verkehrspracheFamilie", (conn, schueler, value, map) -> {
				final String strData = JSONMapper.convertToString(value, true, true, null);
				final Verkehrssprache vs = Verkehrssprache.getByKuerzelAuto(strData);
				if (vs == null)
					throw new ApiOperationException(Status.NOT_FOUND);
				schueler.VerkehrsspracheFamilie = vs;
			}),
			Map.entry("geburtslandVater", (conn, schueler, value, map) -> {
				final String strData = JSONMapper.convertToString(value, true, true, null);
				final Nationalitaeten nat = Nationalitaeten.getByISO3(strData);
				if (nat == null)
					throw new ApiOperationException(Status.NOT_FOUND);
				schueler.GeburtslandVater = nat;
			}),
			Map.entry("geburtslandMutter", (conn, schueler, value, map) -> {
				final String strData = JSONMapper.convertToString(value, true, true, null);
				final Nationalitaeten nat = Nationalitaeten.getByISO3(strData);
				if (nat == null)
					throw new ApiOperationException(Status.NOT_FOUND);
				schueler.GeburtslandMutter = nat;
			}),

			// Statusdaten
			Map.entry("status", (conn, schueler, value, map) -> {
				final SchuelerStatus s = SchuelerStatus.fromID(JSONMapper.convertToInteger(value, false));
				if (s == null)
					throw new ApiOperationException(Status.BAD_REQUEST);
				schueler.Status = s;
			}),
			Map.entry("externeSchulNr", (conn, schueler, value, map) -> {
				final String externeSchulNr = JSONMapper.convertToString(value, true, true, 6);
				if ((externeSchulNr == null) || externeSchulNr.isBlank()) {
					schueler.ExterneSchulNr = null;
				} else {
					if (externeSchulNr.length() != 6)
						throw new ApiOperationException(Status.BAD_REQUEST, "Die Anzahl der Ziffern einer Schulnummer aus NRW muss 6 betragen.");
					schueler.ExterneSchulNr = externeSchulNr;
				}
			}),
			Map.entry("fahrschuelerArtID", (conn, schueler, value, map) -> {
				final Long fid = JSONMapper.convertToLong(value, true);
				if ((fid != null) && (fid < 0))
					throw new ApiOperationException(Status.CONFLICT);
				if (fid == null) {
					schueler.Fahrschueler_ID = null;
				} else {
					final DTOFahrschuelerart f = conn.queryByKey(DTOFahrschuelerart.class, fid);
					if (f == null)
						throw new ApiOperationException(Status.NOT_FOUND);
					schueler.Fahrschueler_ID = fid;
				}
			}),
			Map.entry("haltestelleID", (conn, schueler, value, map) -> {
				final Long hid = JSONMapper.convertToLong(value, true);
				if ((hid != null) && (hid < 0))
					throw new ApiOperationException(Status.CONFLICT);
				if (hid == null) {
					schueler.Haltestelle_ID = null;
				} else {
					final DTOHaltestellen h = conn.queryByKey(DTOHaltestellen.class, hid);
					if (h == null)
						throw new ApiOperationException(Status.NOT_FOUND);
					schueler.Haltestelle_ID = hid;
				}
			}),
			Map.entry("anmeldedatum", (conn, schueler, value, map) -> schueler.AnmeldeDatum = JSONMapper.convertToString(value, true, false, null)),
			Map.entry("aufnahmedatum", (conn, schueler, value, map) -> {
				final String aufnahmedatum = JSONMapper.convertToString(value, true, true, null);
				schueler.Aufnahmedatum = "".equals(aufnahmedatum) ? null : aufnahmedatum;
			}),
			Map.entry("istVolljaehrig", (conn, schueler, value, map) -> schueler.Volljaehrig = JSONMapper.convertToBoolean(value, false)),
			Map.entry("istSchulpflichtErfuellt", (conn, schueler, value, map) -> schueler.SchulpflichtErf = JSONMapper.convertToBoolean(value, false)),
			Map.entry("istBerufsschulpflichtErfuellt", (conn, schueler, value, map) -> schueler.BerufsschulpflErf = JSONMapper.convertToBoolean(value, false)),
			Map.entry("hatMasernimpfnachweis", (conn, schueler, value, map) -> schueler.MasernImpfnachweis = JSONMapper.convertToBoolean(value, false)),
			Map.entry("keineAuskunftAnDritte", (conn, schueler, value, map) -> schueler.KeineAuskunft = JSONMapper.convertToBoolean(value, false)),
			Map.entry("erhaeltSchuelerBAFOEG", (conn, schueler, value, map) -> schueler.Bafoeg = JSONMapper.convertToBoolean(value, false)),
			Map.entry("erhaeltMeisterBAFOEG", (conn, schueler, value, map) -> schueler.MeisterBafoeg = JSONMapper.convertToBoolean(value, false)),
			Map.entry("istDuplikat", (conn, schueler, value, map) -> schueler.Duplikat = JSONMapper.convertToBoolean(value, false)));

	@Override
	public Response patch(final Long id, final InputStream is) throws ApiOperationException {
		return super.patchBasic(id, is, DTOSchueler.class, patchMappings);
	}


	/**
	 * Setzt den Wohnort bei den Schülerdaten und prüft dabei die Angabe des Ortsteils auf Korrektheit in Bezug auf die Ortsteile
	 * in der Datenbank. Ggf. wird der Ortsteil auf null gesetzt.
	 *
	 * @param schueler     das Schüler-DTO der Datenbank
	 * @param wohnortID    die zu setzende Wohnort-ID
	 * @param ortsteilID   die zu setzende O	eil-ID
	 *
	 * @throws ApiOperationException   eine Exception mit dem HTTP-Fehlercode 409, falls die ID negative und damit ungültig ist
	 */
	private void setWohnort(final DTOSchueler schueler, final Long wohnortID, final Long ortsteilID) throws ApiOperationException {
		if ((wohnortID != null) && (wohnortID < 0))
			throw new ApiOperationException(Status.CONFLICT);
		if ((ortsteilID != null) && (ortsteilID < 0))
			throw new ApiOperationException(Status.CONFLICT);
		schueler.Ort_ID = wohnortID;
		// Prüfe, ob die Ortsteil ID in Bezug auf die WohnortID gültig ist, wähle hierbei null-Verweise auf die K_Ort-Tabelle als überall gültig
		Long ortsteilIDNeu = ortsteilID;
		if (ortsteilIDNeu != null) {
			final DTOOrtsteil ortsteil = conn.queryByKey(DTOOrtsteil.class, ortsteilIDNeu);
			if ((ortsteil == null) || ((ortsteil.Ort_ID != null) && (!ortsteil.Ort_ID.equals(wohnortID)))) {
				ortsteilIDNeu = null;
			}
		}
		schueler.Ortsteil_ID = ortsteilIDNeu;
	}


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy