<commit_before>/*******************************************************************************
 * Copyright (c) 2005-2010, <NAME> and Elexis
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    <NAME> - initial implementation
 *    <NAME> - added loadByPatientID
 * 
 *******************************************************************************/
package ch.elexis.data;

import static ch.elexis.core.model.PatientConstants.FLD_EXTINFO_LEGAL_GUARDIAN;
import static ch.elexis.core.model.PatientConstants.FLD_EXTINFO_STAMMARZT;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import ch.elexis.admin.AccessControlDefaults;
import ch.elexis.core.constants.Preferences;
import ch.elexis.core.constants.StringConstants;
import ch.elexis.core.data.activator.CoreHub;
import ch.elexis.core.data.events.ElexisEventDispatcher;
import ch.elexis.core.data.interfaces.events.MessageEvent;
import ch.elexis.core.jdt.Nullable;
import ch.elexis.core.model.prescription.EntryType;
import ch.rgw.tools.ExHandler;
import ch.rgw.tools.JdbcLink;
import ch.rgw.tools.JdbcLink.Stm;
import ch.rgw.tools.Money;
import ch.rgw.tools.StringTool;
import ch.rgw.tools.TimeTool;
import ch.rgw.tools.TimeTool.TimeFormatException;

/**
 * Ein Patient ist eine Person (und damit auch ein Kontakt), mit folgenden zusätzlichen
 * Eigenschaften
 * <ul>
 * <li>Anamnesen : PA, SA, FA</li>
 * <li>Fixe Diagnosen</li>
 * <li>Fixe Medikation</li>
 * <li>Risiken</li>
 * <li>Einer Liste der Fälle, die zu diesem Patienten existieren</li>
 * <li>Einer Liste der Garanten, die diesem Patienten zugeordnet wurden</li>
 * <li>Einer Liste aller Forderungen und Zahlungen im Verkehr mit diesem Patienten</li>
 * </ul>
 * 
 * @author gerry
 * 
 */
public class Patient extends Person {
	
	public static final String FLD_ALLERGIES = "Allergien";
	public static final String FLD_RISKS = "Risiken";
	public static final String FLD_GROUP = "Gruppe";
	public static final String FLD_DIAGNOSES = "Diagnosen";
	public static final String FLD_PATID = "PatientNr";
	public final static String FLD_NAME = "Name";
	public static final String FLD_FIRSTNAME = "Vorname";
	public static final String FLD_SEX = "Geschlecht";
	public static final String FLD_DOB = "Geburtsdatum";
	public static final String FLD_STREET = "Strasse";
	public static final String FLD_ZIP = "Plz";
	public static final String FLD_PLACE = "Ort";
	public static final String FLD_PHONE1 = "Telefon1";
	public static final String FLD_FAX = "Fax";
	public static final String FLD_BALANCE = "Konto";
	public static final String FLD_PERS_ANAMNESE = "PersAnamnese";
	public static final String FLD_SYS_ANAMNESE = "SysAnamnese";
	public static final String FLD_FAM_ANAMNESE = "FamilienAnamnese";
	
	public static final String[] DEFAULT_SORT = {
		FLD_NAME, FLD_FIRSTNAME, FLD_DOB
	};
	
	static {
		addMapping(Kontakt.TABLENAME, FLD_DIAGNOSES + "    	=S:C:Diagnosen",
			FLD_PERS_ANAMNESE + "	=S:C:PersAnamnese", "SystemAnamnese	 	=S:C:SysAnamnese",
			"FamilienAnamnese	=S:C:FamAnamnese", FLD_RISKS, FLD_ALLERGIES,
			"Faelle				=LIST:PatientID:FAELLE:DatumVon",
			"Garanten			=JOINT:GarantID:PatientID:PATIENT_GARANT_JOINT:"
				+ Kontakt.class.getCanonicalName(),
			"Dauermedikation	=JOINT:ArtikelID:PatientID:PATIENT_ARTIKEL_JOINT:"
				+ Artikel.class.getCanonicalName(),
			FLD_BALANCE + "			=LIST:PatientID:KONTO", FLD_GROUP, FLD_PATID,
			Kontakt.FLD_IS_PATIENT);
	}
	
	public String getDiagnosen(){
		return get(FLD_DIAGNOSES);
	}
	
	public String getPersAnamnese(){
		return get("PersAnamnese");
	}
	
	public String getSystemAnamnese(){
		return get("Systemanamnese");
	}
	
	protected Patient(){/* leer */
	}
	
	@Override
	public boolean isValid(){
		if (!super.isValid()) {
			return false;
		}
		String geb = (get(Person.BIRTHDATE));
		if (geb.equals("WERT?")) {
			return false;
		}
		String g = get(Person.SEX);
		if (g.equals(Person.MALE) || g.equals(Person.FEMALE)) {
			return true;
		}
		return false;
	}
	
	/**
	 * Dieser oder der folgende Konstruktor sollte normalerweise verwendet werden, um einen neuen,
	 * bisher noch nicht in der Datenbank vorhandenen Patienten anzulegen.
	 * 
	 * @param Name
	 * @param Vorname
	 * @param Geburtsdatum
	 *            Als String in Notation dd.mm.jj
	 * @param s
	 *            Geschlecht m oder w
	 */
	public Patient(final String Name, final String Vorname, final String Geburtsdatum,
		final String s){
		super(Name, Vorname, Geburtsdatum, s);
		getPatCode();
	}
	
	/**
	 * This constructor is more critical than the previous one
	 * 
	 * @param name
	 *            will be checked for non-alphabetic characters
	 * @param vorname
	 *            will be checked for non alphabetiic characters
	 * @param gebDat
	 *            will be checked for unplausible values
	 * @param s
	 *            will be checked for undefined values
	 * @throws TimeFormatException
	 */
	public Patient(final String name, final String vorname, final TimeTool gebDat, final String s)
		throws PersonDataException{
		super(name, vorname, gebDat, s);
		getPatCode();
	}
	
	/**
	 * Eine Liste aller zu diesem Patient gehörenden Fälle liefern
	 * 
	 * @return Array mit allen Fällen (das die Länge null haben kann)
	 */
	public Fall[] getFaelle(){
		List<String> cas = getList("Faelle", true);
		Fall[] ret = new Fall[cas.size()];
		int i = 0;
		for (String id : cas) {
			Fall fall = Fall.load(id);
			fall.setDBConnection(getDBConnection());
			ret[i++] = fall;
		}
		return ret;
	}
	
	/**
	 * Get the patients active medication filtered by {@link EntryType}.
	 * 
	 * @param filterType
	 *            or null
	 * @return
	 */
	public List<Prescription> getMedication(@Nullable EntryType filterType){
		Query<Prescription> qbe = new Query<Prescription>(Prescription.class);
		qbe.add(Prescription.FLD_PATIENT_ID, Query.EQUALS, getId());
		qbe.add(Prescription.FLD_REZEPT_ID, StringTool.leer, null);
		String today = new TimeTool().toString(TimeTool.DATE_COMPACT);
		qbe.startGroup();
		qbe.add(Prescription.FLD_DATE_UNTIL, Query.GREATER_OR_EQUAL, today);
		qbe.or();
		qbe.add(Prescription.FLD_DATE_UNTIL, StringTool.leer, null);
		qbe.endGroup();
		List<Prescription> prescriptions = qbe.execute();
		
		if (filterType != null) {
			return prescriptions.parallelStream().filter(p -> p.getEntryType() == filterType)
				.collect(Collectors.toList());
		} else {
			return prescriptions;
		}
	}
	
	/**
	 * Get the patients medication filtered by {@link EntryType} as text.
	 * 
	 * @param filterType
	 *            or null
	 * @return
	 */
	public String getMedicationText(@Nullable EntryType filterType){
		List<Prescription> prescriptions = getMedication(filterType);
		StringBuilder sb = new StringBuilder();
		
		prescriptions.stream().forEach(p -> sb.append(p.getLabel()).append(StringTool.lf));
		return sb.toString();
	}
	
	/**
	 * Fixmedikation dieses Patienten einlesen
	 * 
	 * @return ein Array aus {@link Prescription}
	 * @deprecated does not filter by EntryType, use {@link Patient#getMedication(EntryType)}
	 *             instead.
	 */
	public Prescription[] getFixmedikation(){
		Query<Prescription> qbe = new Query<Prescription>(Prescription.class);
		qbe.add(Prescription.FLD_PATIENT_ID, Query.EQUALS, getId());
		qbe.add(Prescription.FLD_REZEPT_ID, StringTool.leer, null);
		String today = new TimeTool().toString(TimeTool.DATE_COMPACT);
		qbe.startGroup();
		qbe.add(Prescription.FLD_DATE_UNTIL, Query.GREATER_OR_EQUAL, today);
		qbe.or();
		qbe.add(Prescription.FLD_DATE_UNTIL, StringTool.leer, null);
		qbe.endGroup();
		List<Prescription> l = qbe.execute();
		
		return l.toArray(new Prescription[0]);
	}
	
	/**
	 * Fixmedikation als Text
	 * 
	 * @return
	 * @deprecated does not filter by EntryType, use {@link Patient#getMedication(EntryType)}
	 *             instead.
	 */
	public String getMedikation(){
		Prescription[] pre = getFixmedikation();
		StringBuilder sb = new StringBuilder();
		for (Prescription p : pre) {
			sb.append(p.getLabel()).append(StringTool.lf);
		}
		return sb.toString();
	}
	
	/**
	 * Die neueste Konsultation dieses Patienten holen, soweit eruierbar
	 * 
	 * @param create
	 *            : eine Kons erstellen, falls keine existiert
	 * @return die letzte Konsultation oder null
	 */
	
	public Konsultation getLetzteKons(final boolean create){
		if (ElexisEventDispatcher.getSelectedMandator() == null) {
			MessageEvent.fireError("Kein Mandant angemeldet", "Es ist kein Mandant angemeldet.");
			return null;
		}
		Query<Konsultation> qbe = new Query<Konsultation>(Konsultation.class);
		
		// if not configured otherwise load only consultations of active mandant
		if (!CoreHub.userCfg.get(Preferences.USR_DEFLOADCONSALL, false)) {
			Mandant mandator = ElexisEventDispatcher.getSelectedMandator();
			if (mandator != null) {
				qbe.add(Konsultation.FLD_MANDATOR_ID, Query.EQUALS, mandator.getId());
			}
		}
		
		// qbe.add("Datum", "=", new
		// TimeTool().toString(TimeTool.DATE_COMPACT));
		
		Fall[] faelle = getFaelle();
		if ((faelle == null) || (faelle.length == 0)) {
			return create ? createFallUndKons() : null;
		}
		qbe.startGroup();
		boolean termInserted = false;
		for (Fall fall : faelle) {
			if (fall.isOpen()) {
				qbe.add(Konsultation.FLD_CASE_ID, Query.EQUALS, fall.getId());
				qbe.or();
				termInserted = true;
			}
		}
		if (!termInserted) {
			return create ? createFallUndKons() : null;
		}
		qbe.endGroup();
		qbe.orderBy(true, Konsultation.DATE);
		List<Konsultation> list = qbe.execute();
		if ((list == null) || list.isEmpty()) {
			return null;
		} else {
			return list.get(0);
		}
	}
	
	public Konsultation createFallUndKons(){
		Fall fall = neuerFall(Fall.getDefaultCaseLabel(), Fall.getDefaultCaseReason(),
			Fall.getDefaultCaseLaw());
		Konsultation k = fall.neueKonsultation();
		k.setMandant(ElexisEventDispatcher.getSelectedMandator());
		return k;
	}
	
	/**
	 * Einen neuen Fall erstellen und an den Patienten binden
	 * 
	 * @return der eben erstellte Fall oder null bei Fehler
	 */
	public Fall neuerFall(final String Bezeichnung, final String grund,
		final String Abrechnungsmethode){
		Fall fall = new Fall(getId(), Bezeichnung, grund, Abrechnungsmethode);
		ElexisEventDispatcher.reload(Fall.class);
		return fall;
	}
	
	/**
	 * Einen Kurzcode, der diesen Patienten identifiziert, zurückliefern. Der Kurzcode kann je nach
	 * Voreinstellung eine eindeutige, jeweils nur einmal vergebene Nummer sein, oder ein aus den
	 * Personalien gebildetes Kürzel. Dieser Code kann beispielsweise als Index für die Archivierung
	 * der KG's in Papierform verwendet werden.
	 * 
	 * @return einen String, (der eine Zahl sein kann), und der innerhalb dieser Installation
	 *         eindeutig ist.
	 */
	public String getPatCode(){
		String rc = get(FLD_PATID);
		if (!StringTool.isNothing(rc)) {
			return rc;
		}
		while (true) {
			String lockid = PersistentObject.lock("PatNummer", true);
			String pid = getDBConnection()
				.queryString("SELECT WERT FROM CONFIG WHERE PARAM='PatientNummer'");
			if (StringTool.isNothing(pid)) {
				pid = "0";
				getDBConnection()
					.exec("INSERT INTO CONFIG (PARAM,WERT) VALUES ('PatientNummer','0')");
			}
			int lastNum = Integer.parseInt(pid) + 1;
			rc = Integer.toString(lastNum);
			getDBConnection()
				.exec("UPDATE CONFIG set wert='" + rc + "' where param='PatientNummer'");
			PersistentObject.unlock("PatNummer", lockid);
			String exists = getDBConnection()
				.queryString("SELECT ID FROM KONTAKT WHERE PatientNr=" + JdbcLink.wrap(rc));
			if (exists == null) {
				break;
			}
		}
		set(FLD_PATID, rc);
		return rc;
	}
	
	public Money getKontostand(){
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT betrag FROM KONTO WHERE PatientID=").append(getWrappedId());
		Stm stm = getDBConnection().getStatement();
		Money konto = new Money();
		try {
			ResultSet res = stm.query(sql.toString());
			while (res.next()) {
				int buchung = res.getInt(1);
				konto.addCent(buchung);
			}
			return konto;
		} catch (Exception ex) {
			ExHandler.handle(ex);
			return null;
		} finally {
			getDBConnection().releaseStatement(stm);
		}
	}
	<commit_msg>[5098] update lastupdate when setting PatientNummer in global config<commit_after>/*******************************************************************************
 * Copyright (c) 2005-2010, <NAME> and Elexis
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    <NAME> - initial implementation
 *    <NAME> - added loadByPatientID
 * 
 *******************************************************************************/
package ch.elexis.data;

import static ch.elexis.core.model.PatientConstants.FLD_EXTINFO_LEGAL_GUARDIAN;
import static ch.elexis.core.model.PatientConstants.FLD_EXTINFO_STAMMARZT;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import ch.elexis.admin.AccessControlDefaults;
import ch.elexis.core.constants.Preferences;
import ch.elexis.core.constants.StringConstants;
import ch.elexis.core.data.activator.CoreHub;
import ch.elexis.core.data.events.ElexisEventDispatcher;
import ch.elexis.core.data.interfaces.events.MessageEvent;
import ch.elexis.core.jdt.Nullable;
import ch.elexis.core.model.prescription.EntryType;
import ch.rgw.tools.ExHandler;
import ch.rgw.tools.JdbcLink;
import ch.rgw.tools.JdbcLink.Stm;
import ch.rgw.tools.Money;
import ch.rgw.tools.StringTool;
import ch.rgw.tools.TimeTool;
import ch.rgw.tools.TimeTool.TimeFormatException;

/**
 * Ein Patient ist eine Person (und damit auch ein Kontakt), mit folgenden zusätzlichen
 * Eigenschaften
 * <ul>
 * <li>Anamnesen : PA, SA, FA</li>
 * <li>Fixe Diagnosen</li>
 * <li>Fixe Medikation</li>
 * <li>Risiken</li>
 * <li>Einer Liste der Fälle, die zu diesem Patienten existieren</li>
 * <li>Einer Liste der Garanten, die diesem Patienten zugeordnet wurden</li>
 * <li>Einer Liste aller Forderungen und Zahlungen im Verkehr mit diesem Patienten</li>
 * </ul>
 * 
 * @author gerry
 * 
 */
public class Patient extends Person {
	
	public static final String FLD_ALLERGIES = "Allergien";
	public static final String FLD_RISKS = "Risiken";
	public static final String FLD_GROUP = "Gruppe";
	public static final String FLD_DIAGNOSES = "Diagnosen";
	public static final String FLD_PATID = "PatientNr";
	public final static String FLD_NAME = "Name";
	public static final String FLD_FIRSTNAME = "Vorname";
	public static final String FLD_SEX = "Geschlecht";
	public static final String FLD_DOB = "Geburtsdatum";
	public static final String FLD_STREET = "Strasse";
	public static final String FLD_ZIP = "Plz";
	public static final String FLD_PLACE = "Ort";
	public static final String FLD_PHONE1 = "Telefon1";
	public static final String FLD_FAX = "Fax";
	public static final String FLD_BALANCE = "Konto";
	public static final String FLD_PERS_ANAMNESE = "PersAnamnese";
	public static final String FLD_SYS_ANAMNESE = "SysAnamnese";
	public static final String FLD_FAM_ANAMNESE = "FamilienAnamnese";
	
	public static final String[] DEFAULT_SORT = {
		FLD_NAME, FLD_FIRSTNAME, FLD_DOB
	};
	
	static {
		addMapping(Kontakt.TABLENAME, FLD_DIAGNOSES + "    	=S:C:Diagnosen",
			FLD_PERS_ANAMNESE + "	=S:C:PersAnamnese", "SystemAnamnese	 	=S:C:SysAnamnese",
			"FamilienAnamnese	=S:C:FamAnamnese", FLD_RISKS, FLD_ALLERGIES,
			"Faelle				=LIST:PatientID:FAELLE:DatumVon",
			"Garanten			=JOINT:GarantID:PatientID:PATIENT_GARANT_JOINT:"
				+ Kontakt.class.getCanonicalName(),
			"Dauermedikation	=JOINT:ArtikelID:PatientID:PATIENT_ARTIKEL_JOINT:"
				+ Artikel.class.getCanonicalName(),
			FLD_BALANCE + "			=LIST:PatientID:KONTO", FLD_GROUP, FLD_PATID,
			Kontakt.FLD_IS_PATIENT);
	}
	
	public String getDiagnosen(){
		return get(FLD_DIAGNOSES);
	}
	
	public String getPersAnamnese(){
		return get("PersAnamnese");
	}
	
	public String getSystemAnamnese(){
		return get("Systemanamnese");
	}
	
	protected Patient(){/* leer */
	}
	
	@Override
	public boolean isValid(){
		if (!super.isValid()) {
			return false;
		}
		String geb = (get(Person.BIRTHDATE));
		if (geb.equals("WERT?")) {
			return false;
		}
		String g = get(Person.SEX);
		if (g.equals(Person.MALE) || g.equals(Person.FEMALE)) {
			return true;
		}
		return false;
	}
	
	/**
	 * Dieser oder der folgende Konstruktor sollte normalerweise verwendet werden, um einen neuen,
	 * bisher noch nicht in der Datenbank vorhandenen Patienten anzulegen.
	 * 
	 * @param Name
	 * @param Vorname
	 * @param Geburtsdatum
	 *            Als String in Notation dd.mm.jj
	 * @param s
	 *            Geschlecht m oder w
	 */
	public Patient(final String Name, final String Vorname, final String Geburtsdatum,
		final String s){
		super(Name, Vorname, Geburtsdatum, s);
		getPatCode();
	}
	
	/**
	 * This constructor is more critical than the previous one
	 * 
	 * @param name
	 *            will be checked for non-alphabetic characters
	 * @param vorname
	 *            will be checked for non alphabetiic characters
	 * @param gebDat
	 *            will be checked for unplausible values
	 * @param s
	 *            will be checked for undefined values
	 * @throws TimeFormatException
	 */
	public Patient(final String name, final String vorname, final TimeTool gebDat, final String s)
		throws PersonDataException{
		super(name, vorname, gebDat, s);
		getPatCode();
	}
	
	/**
	 * Eine Liste aller zu diesem Patient gehörenden Fälle liefern
	 * 
	 * @return Array mit allen Fällen (das die Länge null haben kann)
	 */
	public Fall[] getFaelle(){
		List<String> cas = getList("Faelle", true);
		Fall[] ret = new Fall[cas.size()];
		int i = 0;
		for (String id : cas) {
			Fall fall = Fall.load(id);
			fall.setDBConnection(getDBConnection());
			ret[i++] = fall;
		}
		return ret;
	}
	
	/**
	 * Get the patients active medication filtered by {@link EntryType}.
	 * 
	 * @param filterType
	 *            or null
	 * @return
	 */
	public List<Prescription> getMedication(@Nullable EntryType filterType){
		Query<Prescription> qbe = new Query<Prescription>(Prescription.class);
		qbe.add(Prescription.FLD_PATIENT_ID, Query.EQUALS, getId());
		qbe.add(Prescription.FLD_REZEPT_ID, StringTool.leer, null);
		String today = new TimeTool().toString(TimeTool.DATE_COMPACT);
		qbe.startGroup();
		qbe.add(Prescription.FLD_DATE_UNTIL, Query.GREATER_OR_EQUAL, today);
		qbe.or();
		qbe.add(Prescription.FLD_DATE_UNTIL, StringTool.leer, null);
		qbe.endGroup();
		List<Prescription> prescriptions = qbe.execute();
		
		if (filterType != null) {
			return prescriptions.parallelStream().filter(p -> p.getEntryType() == filterType)
				.collect(Collectors.toList());
		} else {
			return prescriptions;
		}
	}
	
	/**
	 * Get the patients medication filtered by {@link EntryType} as text.
	 * 
	 * @param filterType
	 *            or null
	 * @return
	 */
	public String getMedicationText(@Nullable EntryType filterType){
		List<Prescription> prescriptions = getMedication(filterType);
		StringBuilder sb = new StringBuilder();
		
		prescriptions.stream().forEach(p -> sb.append(p.getLabel()).append(StringTool.lf));
		return sb.toString();
	}
	
	/**
	 * Fixmedikation dieses Patienten einlesen
	 * 
	 * @return ein Array aus {@link Prescription}
	 * @deprecated does not filter by EntryType, use {@link Patient#getMedication(EntryType)}
	 *             instead.
	 */
	public Prescription[] getFixmedikation(){
		Query<Prescription> qbe = new Query<Prescription>(Prescription.class);
		qbe.add(Prescription.FLD_PATIENT_ID, Query.EQUALS, getId());
		qbe.add(Prescription.FLD_REZEPT_ID, StringTool.leer, null);
		String today = new TimeTool().toString(TimeTool.DATE_COMPACT);
		qbe.startGroup();
		qbe.add(Prescription.FLD_DATE_UNTIL, Query.GREATER_OR_EQUAL, today);
		qbe.or();
		qbe.add(Prescription.FLD_DATE_UNTIL, StringTool.leer, null);
		qbe.endGroup();
		List<Prescription> l = qbe.execute();
		
		return l.toArray(new Prescription[0]);
	}
	
	/**
	 * Fixmedikation als Text
	 * 
	 * @return
	 * @deprecated does not filter by EntryType, use {@link Patient#getMedication(EntryType)}
	 *             instead.
	 */
	public String getMedikation(){
		Prescription[] pre = getFixmedikation();
		StringBuilder sb = new StringBuilder();
		for (Prescription p : pre) {
			sb.append(p.getLabel()).append(StringTool.lf);
		}
		return sb.toString();
	}
	
	/**
	 * Die neueste Konsultation dieses Patienten holen, soweit eruierbar
	 * 
	 * @param create
	 *            : eine Kons erstellen, falls keine existiert
	 * @return die letzte Konsultation oder null
	 */
	
	public Konsultation getLetzteKons(final boolean create){
		if (ElexisEventDispatcher.getSelectedMandator() == null) {
			MessageEvent.fireError("Kein Mandant angemeldet", "Es ist kein Mandant angemeldet.");
			return null;
		}
		Query<Konsultation> qbe = new Query<Konsultation>(Konsultation.class);
		
		// if not configured otherwise load only consultations of active mandant
		if (!CoreHub.userCfg.get(Preferences.USR_DEFLOADCONSALL, false)) {
			Mandant mandator = ElexisEventDispatcher.getSelectedMandator();
			if (mandator != null) {
				qbe.add(Konsultation.FLD_MANDATOR_ID, Query.EQUALS, mandator.getId());
			}
		}
		
		// qbe.add("Datum", "=", new
		// TimeTool().toString(TimeTool.DATE_COMPACT));
		
		Fall[] faelle = getFaelle();
		if ((faelle == null) || (faelle.length == 0)) {
			return create ? createFallUndKons() : null;
		}
		qbe.startGroup();
		boolean termInserted = false;
		for (Fall fall : faelle) {
			if (fall.isOpen()) {
				qbe.add(Konsultation.FLD_CASE_ID, Query.EQUALS, fall.getId());
				qbe.or();
				termInserted = true;
			}
		}
		if (!termInserted) {
			return create ? createFallUndKons() : null;
		}
		qbe.endGroup();
		qbe.orderBy(true, Konsultation.DATE);
		List<Konsultation> list = qbe.execute();
		if ((list == null) || list.isEmpty()) {
			return null;
		} else {
			return list.get(0);
		}
	}
	
	public Konsultation createFallUndKons(){
		Fall fall = neuerFall(Fall.getDefaultCaseLabel(), Fall.getDefaultCaseReason(),
			Fall.getDefaultCaseLaw());
		Konsultation k = fall.neueKonsultation();
		k.setMandant(ElexisEventDispatcher.getSelectedMandator());
		return k;
	}
	
	/**
	 * Einen neuen Fall erstellen und an den Patienten binden
	 * 
	 * @return der eben erstellte Fall oder null bei Fehler
	 */
	public Fall neuerFall(final String Bezeichnung, final String grund,
		final String Abrechnungsmethode){
		Fall fall = new Fall(getId(), Bezeichnung, grund, Abrechnungsmethode);
		ElexisEventDispatcher.reload(Fall.class);
		return fall;
	}
	
	/**
	 * Einen Kurzcode, der diesen Patienten identifiziert, zurückliefern. Der Kurzcode kann je nach
	 * Voreinstellung eine eindeutige, jeweils nur einmal vergebene Nummer sein, oder ein aus den
	 * Personalien gebildetes Kürzel. Dieser Code kann beispielsweise als Index für die Archivierung
	 * der KG's in Papierform verwendet werden.
	 * 
	 * @return einen String, (der eine Zahl sein kann), und der innerhalb dieser Installation
	 *         eindeutig ist.
	 */
	public String getPatCode(){
		String rc = get(FLD_PATID);
		if (!StringTool.isNothing(rc)) {
			return rc;
		}
		while (true) {
			String lockid = PersistentObject.lock("PatNummer", true);
			String pid = getDBConnection()
				.queryString("SELECT WERT FROM CONFIG WHERE PARAM='PatientNummer'");
			if (StringTool.isNothing(pid)) {
				pid = "0";
				getDBConnection()
					.exec("INSERT INTO CONFIG (PARAM,WERT) VALUES ('PatientNummer','0')");
			}
			int lastNum = Integer.parseInt(pid) + 1;
			rc = Integer.toString(lastNum);
			getDBConnection().exec("UPDATE CONFIG set wert='" + rc + "', lastupdate="
				+ Long.toString(System.currentTimeMillis()) + " where param='PatientNummer'");
			PersistentObject.unlock("PatNummer", lockid);
			String exists = getDBConnection()
				.queryString("SELECT ID FROM KONTAKT WHERE PatientNr=" + JdbcLink.wrap(rc));
			if (exists == null) {
				break;
			}
		}
		set(FLD_PATID, rc);
		return rc;
	}
	
	public Money getKontostand(){
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT betrag FROM KONTO WHERE PatientID=").append(getWrappedId());
		Stm stm = getDBConnection().getStatement();
		Money konto = new Money();
		try {
			ResultSet res = stm.query(sql.toString());
			while (res.next()) {
				int buchung = res.getInt(1);
				konto.addCent(buchung);
			}
			return konto;
		} catch (Exception ex) {
			ExHandler.handle(ex);
			return null;
		} finally {
			getDBConnection().releaseStatement(stm);
		}
	}
	
{'fraction_non_alphanumeric': 0.12884027666076886, 'fraction_numerical': 0.0019301914106482226, 'mean_word_length': 4.08256693235234, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7144762', 'n_tokens_mistral': 9196, 'n_tokens_neox': 8325, 'n_words': 2033}