Index: trunk/info/info/alkisn/alkisfkt.php
===================================================================
--- trunk/info/info/alkisn/alkisfkt.php	(revision 422)
+++ trunk/info/info/alkisn/alkisfkt.php	(revision 425)
@@ -6,5 +6,5 @@
 
 	Version:
-	2016-02-24 Version fuer norGIS-ALKIS-Import, "function linkgml" raus. Case-EntschlÃŒsselung raus.
+	2016-02-24 Version fÃŒr norGIS-ALKIS-Import, "function linkgml" raus. Case-EntschlÃŒsselung raus.
 	....
 	2020-12-03 function selbstverlinkung() statt $_SERVER['PHP_SELF'] fÃŒr Einsatz hinter Gateway mit Ãnderung des Pfades (Docker/QWC2)
@@ -12,4 +12,10 @@
 	2020-12-15 Input-Validation und Strict Comparisation (===)
 	2020-12-16 Sonderfall QWC2 API-Gateway-Umleitung bei Selbstverlinkung
+	2021-12-09 Neue Parameter: $katAmtMix (Kataster-Amt-Mix), $PrntBtn (Drucken-SchaltflÃ€che)
+			   Footer: Umschalter fÃŒr SchlÃŒssel und Debug unabhÃ€ngig benutzbar. Authentifizierung aus QWC2 nicht hier behandeln.
+	2021-12-30 Bestandsnachweis recursiv ÃŒber alle Buchungs-Ebenen
+
+++ ToDo:
+	- Parameter $lnkclass in eigentuemer() und $jfenster in buchung_anzg() vereinheitlichen
 */
 
@@ -17,6 +23,5 @@
 //	Aus der Server-Variable den Pfad entfernen.
 	global $pfadlos_selbstlink;
-	If ($pfadlos_selbstlink === 1) { // pfad-lose Selbstverlinkung hinter einer Umleitung. z.B. QWC2 API-Gateway
-		// Pfad entfernen
+	If ($pfadlos_selbstlink === 1) { // Selbstverlinkung ohne Pfad z.B. hinter QWC2 API-Gateway (Umleitung)
 		$mod=strrchr($_SERVER['PHP_SELF'], '/');
 		$mod=substr($mod, 1);
@@ -29,26 +34,21 @@
 function darf_ich() {
 //	Am Anfang jedes Moduls aufrufen um $customer zu fÃŒllen.	
-//	Nach EinfÃŒhrung eines automatisch einloggenden anonymen Mapbender-Gast-Benutzers muss dieser bei der Authentifizierung ausgeschlossen werden.
-	global $auth, $customer, $mb_guest_user, $debug;
-
-	if ($auth === "") {	// nicht prÃŒfen
-	//	if ($debug > 1) {echo "\n<p class='dbg'>keine Berechtigungs-PrÃŒfung</p>";}
-		$customer = "(unbekannt)";
-		return 1;	// alles erlaubt
-
+//	Der automatisch einloggende anonyme Gast-Benutzers muss bei der Authentifizierung ausgeschlossen werden.
+	global $auth, $customer, $mb_guest_user, $dbg;
+
+	if ($auth === "") {		// nicht prÃŒfen
+		$customer = "";		// dann anonym
+		return 1;			// alles erlaubt
 	} elseif ($auth === "mapbender") {
-
-	//	if ($debug > 1) {echo "\n<p class='dbg' Berechtigungs-Pr&uuml;fung Mapbender</p>";}
 		$customer = "";
 		include '/opt/gdi/mapbender/http/php/mb_validateSession.php';
-		
+
 		if (!isset($_SESSION)) { // keine (passende) Session
-			if ($debug > 1) {echo "\n<p class='dbg'>Session nicht gesetzt</p>";}
+			if ($dbg > 1) {echo "\n<p class='dbg'>Session nicht gesetzt</p>";}
 		} elseif ( !isset($_SESSION["mb_user_name"]) )  {
-			if ($debug > 1) {echo "\n<p class='dbg'>username nicht gesetzt</p>";}
+			if ($dbg > 1) {echo "\n<p class='dbg'>username nicht gesetzt</p>";}
 		} else {
 			$customer = $_SESSION["mb_user_name"]; // angemeldeter Benutzer	
 		}
-		//if ($debug > 1) {echo "\n<p class='dbg'>Customer '".$customer."'</p>";}
 		if ($customer == "") {	// Wer bin ich?
 			echo "<p class='stop2'>Aufruf nur aus Mapbender erlaubt.</p>";
@@ -60,19 +60,6 @@
 			return 1;	// echter User, ist erlaubt
 		}
-
-	} elseif ($auth === "qwc2") {
-
-		if ($debug > 1) {echo "\n<p class='dbg'>Berechtigungs-PrÃŒfung QWC2 -GEPLANT-</p>";}
-
-		// BAUSTELLE: Hier den Code einfÃŒgen um im QWC2 die Berechtigung zu prÃŒfen und den Benutzer auszulesen.
-		// Guggs du: https://git.sourcepole.ch/krz_dt/qwc2/-/issues/78
-
-		$customer = "(Unbekannt)";
-		echo "<p class='stop2'>Berechtigungspr&uuml;fung fÃŒr QWC2 ist noch nicht m&ouml;glich.</p>";
-		return 1;	// vorlÃ€ufig erlaubt
-
 	} else {
-
-		echo "\n<p class='stop2'>Die Berechtigungs-PrÃŒfung ist falsch konfiguriert</p>";
+		echo "\n<p class='stop2'>Die Berechtigungs-Pr&uuml;fung ist falsch konfiguriert</p>";
 		return 0;	// verboten
 	}
@@ -80,48 +67,74 @@
 
 function footer($gmlid, $link, $append) {
-	// Einen Seitenfuss ausgeben.
+	// Einen SeitenfuÃ ausgeben.
 	// Die Parameter &gkz= und &gmlid= kommen in allen Modulen einheitlich vor
 	// Den URL-Parameter "&showkey=j/n" umschalten lassen.
-	// $append wird angehaengt wenn gefuellt. Anwendung: &eig=j bei FS-NW, &ltyp=m/p/o bei Lage
-	global $gkz, $showkey, $hilfeurl, $debug, $customer;
-
-	echo "<footer>";
+	// $append wird angehÃ€ngt wenn gefÃŒllt. Anwendung: &eig=j bei FSNW, &ltyp=m/p/o bei Lage
+	global $gkz, $showkey, $hilfeurl, $debug, $dbg, $customer;
+
+	echo "\n<footer>";
 	// S c r e e n - F o o t
-	echo "\n<div class='confbereich noprint'>"
-	."\n\t<table class='outer'>\n\t<tr>";
+	echo "\n\t<div class='confbereich noprint'>"
+	."\n\t\t<table class='outer'>\n\t\t<tr>";
 
 	// Spalte 1: Info Benutzerkennung
-	if (isset($customer)) { // ÃŒber global von fkt. darf_ich()
-		echo "\n\t\t<td title='Info'><i>Benutzer:&nbsp;".$customer."</i></td>";
+	if (isset($customer) and $customer != '') { // ÃŒber global von fkt. darf_ich()
+		echo "\n\t\t\t<td title='Info'><i>Benutzer:&nbsp;".$customer."</i></td>";
 	} else {
-		echo "\n\t\t<td>&nbsp;</td>";
+		echo "\n\t\t\t<td>&nbsp;</td>";
 	}
 
 	// Spalte 2: Umschalter
-	echo "\n\t\t<td title='Konfiguration'>";
-		$mylink ="\n\t\t\t<a class='keyswitch' href='".$link."gkz=".$gkz."&amp;gmlid=".$gmlid.$append;
+	echo "\n\t\t\t<td title='Konfiguration'>";
+		$mylink ="\n\t\t\t\t<a class='keyswitch' href='".$link."gkz=".$gkz."&amp;gmlid=".$gmlid.$append;
+
 		if ($showkey) { // Umschalten SchlÃŒssel ein/aus
-			echo $mylink."&amp;showkey=n' title='Verschl&uuml;sselungen ausblenden'>Schl&uuml;ssel aus</a>";
+			echo $mylink."&amp;showkey=n";
+			if ($debug > 0 and $dbg == 0) {echo "&amp;nodebug=j";}
+			echo "' title='Verschl&uuml;sselungen ausblenden'>Schl&uuml;ssel aus</a>";
+			$mylink.="&amp;showkey=j";
 		} else {
-			echo $mylink."&amp;showkey=j' title='Verschl&uuml;sselungen anzeigen'>Schl&uuml;ssel ein</a>";
-		}
-		if ($debug > 0) { // FÃŒr Entwickler temporÃ€r eine Ansicht OHNE debug
-			echo "<br>".$mylink."&amp;nodebug=j' title='Debug-Ausgaben tempor&auml;r abschalten'>Ansicht ohne Testausgaben</a>";
-		}
-	echo "\n\t\t</td>";
-
-	// Spalte 3
-	echo "\n\t\t<td title='Hilfe'>"
-		."\n\t\t\t<p class='nwlink'>\n\t\t\t\t<a target='_blank' href='".$hilfeurl."' title='Dokumentation'>Hilfe zur ALKIS-Auskunft</a>\n\t\t\t</p>\n\t\t</td>"
-		."\n\t</tr>\n\t</table>"
-	."\n</div>\n";
+			echo $mylink."&amp;showkey=j";
+			if ($debug > 0 and $dbg == 0) {echo "&amp;nodebug=j";}
+			echo "' title='Verschl&uuml;sselungen anzeigen'>Schl&uuml;ssel ein</a>";
+			$mylink.="&amp;showkey=n";
+		}
+
+		if ($debug > 0) {	// nur fÃŒr Entwicklung
+			if ($dbg > 0) {	// temporÃ€r eine Ansicht OHNE debug
+				echo "<br>".$mylink."&amp;nodebug=j' title='Debug-Ausgaben tempor&auml;r abschalten'>Testausgaben aus</a>";
+			} else {		// Abschaltung beenden
+				echo "<br>".$mylink."' title='Debug-Ausgaben wie konfiguriert'>Testausgaben ein</a>";
+			}
+		}
+
+	echo "\n\t\t\t</td>";
+
+	// Spalte 3: Dokumentation
+	echo "\n\t\t\t<td title='Hilfe'>"
+		."\n\t\t\t\t<p class='nwlink'>\n\t\t\t\t\t<a target='_blank' href='".$hilfeurl."' title='Dokumentation'>Hilfe zur ALKIS-Auskunft</a>\n\t\t\t\t</p>\n\t\t\t</td>"
+		."\n\t\t</tr>\n\t\t</table>"
+	."\n\t</div>";
 
 	// P r i n t - F o o t
-	if (isset($customer)) {
-		echo "\n<p class='onlyprint'><i>Benutzer:&nbsp;".$customer."</i></p>";
-	}
-
-	echo "</footer>";
+	if (isset($customer) and $customer != '') {
+		echo "\n\t<p class='onlyprint'><i>Benutzer:&nbsp;".$customer."</i></p>";
+	}
+
+	echo "\n</footer>\n";
 	return 0;
+}
+
+function UnqKatAmt($t1, $t2){
+// Wenn der Datenbestand aus NBA-Verfahren mehrerer KatasterÃ€mter gemixt wurde, dann muss beim SQL-JOIN auf einige SchlÃŒsseltabellen
+// zusÃ€tzlich dafÃŒr gesort werden, dass nur die SchlÃŒssel des gleichen Katasteramtes verwendet werden. Sont bekommt man redundante Treffer.
+// BenÃ¶tigt den Alias der zu verbindenden Tabellen.
+// Liefert einen String zum EinfÃŒgen hinter "JOIN .. ON".
+	global $katAmtMix; // aus Conf
+	if ($katAmtMix){
+		return "AND substr(".$t1.".gml_id,1,6) = substr(".$t2.".gml_id,1,6) ";
+	} else {
+		return "";
+	}
 }
 
@@ -150,5 +163,5 @@
 	//  $gml_fs: GML-ID des FlurstÃŒcke (nur bei erstem Aufruf in einem FS-Nachweis notwendig)
 	//	$trtyp: Tabellen-Zeilen-Typ. Werte: 1="mit GS-Link", 2="ohne GS-Link", 3="ohne GS-Link +Zeile einfÃ€rben"
-	global $gkz, $debug, $showkey, $bartgrp, $barttypgrp, $stufe;
+	global $gkz, $dbg, $showkey, $bartgrp, $barttypgrp, $stufe, $katAmtMix;
 
 	$sqlbs="SELECT sh.gml_id AS hgml, sh.buchungsart, sh.laufendenummer as lfd, sh.zaehler, sh.nenner, sh.nummerimaufteilungsplan as nrpl, sh.beschreibungdessondereigentums as sond, " // Buchungs-Stelle herrschend
@@ -156,5 +169,5 @@
 	."FROM ax_buchungsstelle sh "
 	."JOIN ax_buchungsblatt b ON b.gml_id=sh.istbestandteilvon "
-	."LEFT JOIN ax_buchungsblattbezirk z ON z.land=b.land AND z.bezirk=b.bezirk "
+	."LEFT JOIN ax_buchungsblattbezirk z ON z.land=b.land AND z.bezirk=b.bezirk ".UnqKatAmt("z","b")
 	."LEFT JOIN ax_buchungsart_buchungsstelle a ON sh.buchungsart = a.wert " // entschl. Buchungsart
 	."LEFT JOIN ax_blattart_buchungsblatt w ON b.blattart = w.wert " // entschl. Blatt-Art
@@ -166,11 +179,17 @@
 	if (!$resbs) {
 		echo "\n<p class='err'>Fehler bei 'Buchungsstelle ausgeben'.</p>";
-		if ($debug > 2) {echo "\n<p class='dbg'>SQL=<br>".htmlentities(str_replace("$1", "'".$gmlbs."'", $sqlbs), ENT_QUOTES, "UTF-8")."</p>";}
+		if ($dbg > 2) {echo "\n<p class='dbg'>SQL=<br>".htmlentities(str_replace("$1", "'".$gmlbs."'", $sqlbs), ENT_QUOTES, "UTF-8")."</p>";}
 	}
 	$gezeigt = 0; // Funktionswert default
-
-	if ($rowbs = pg_fetch_assoc($resbs)) { // ein Treffer
+	if ($dbg > 0) {
+		$zeianz=pg_num_rows($resbs);
+		if ($zeianz > 1){
+			echo "\n<p class='err'>Die Abfrage liefert mehr als eine (".$zeianz.") Buchung!</p>";
+			if ($dbg > 2) {echo "\n<p class='dbg'>SQL=<br>".htmlentities(str_replace("$1","'".$gmlid."'",$sqlbs), ENT_QUOTES, "UTF-8")."</p>";}
+		}
+	}
+	if ($rowbs = pg_fetch_assoc($resbs)) { // EIN Treffer
 		$blattkeyber=$rowbs["blattart"]; // Schluessel von Blatt-Art des GB
-		if ($blattkeyber != '5000' or $debug > 1) { // "Fiktives Blatt" nur bei Entwicklung anzeigen
+		if ($blattkeyber != '5000' or $dbg > 1) { // "Fiktives Blatt" nur bei Entwicklung anzeigen
 			$gezeigt = 1; // Funktionswert nach Treffer
 			$hgml=$rowbs["hgml"]; // GML-ID der (herrschenden) BuchungsStelle
@@ -218,9 +237,9 @@
 				}
 
-				// +++ mehr Abstand oben zur Zeile in .css?
+				// ++ mehr Abstand oben zur Zeile in .css?
 				echo "\n\t<tr>" // Buchungsart als Zwischenzeile
 					."\n\t\t<td class='ll'><img src='ico/Grundbuch.png' width='16' height='16' alt=''> Buchungsart:</td>" // 1
 					."\n\t\t<td colspan='2' title='".$barttitle."'>"; // 2-3
-						if ($showkey) {echo "<span class='key'>(".$bartkey.")</span> ";}
+						if ($showkey) {echo "<span class='key' title='Buchungsart'>(".$bartkey.")</span> ";}
 						echo "<span class='wichtig'>".$bart."</span>"
 					."</td>"
@@ -232,5 +251,5 @@
 			echo "\n\t<tr>" // Zeile mit 4 Spalten fÃŒr Buchung und EigentÃŒmer
 				."\n\t\t<td class='ll'><img src='ico/Grundbuch_zu.png' width='16' height='16' alt=''> Buchung:"; // 1
-			if ($showkey and $debug > 2) {echo "<br><span class='key'>Stufe ".$stufe."<br>".$hgml."</span> ";}
+			if ($showkey and $dbg > 2) {echo "<br><span class='key'>Stufe ".$stufe."<br>".$hgml."</span> ";}
 			echo "</td>\n\t\t<td colspan='2'>"; // 2-3
 
@@ -244,5 +263,5 @@
 						."\n\t\t\t\t<td class='head'>Bezirk</td>"
 						."\n\t\t\t\t<td class='head'>";
-						if ($showkey) {echo "<span class='key'>".$blattkeyber."</span> ";}
+						if ($showkey) {echo "<span class='key' title='Blattart'>(".$blattkeyber.")</span> ";}
 						echo $blattartber."</td>"
 						."\n\t\t\t\t<td class='head'>Lfd-Nr</td>"
@@ -255,5 +274,5 @@
 					}
 					echo "\n\t\t\t\t<td title='Grundbuchbezirk'>";
-						if ($showkey) {echo "<span class='key'>".$rowbs["bezirk"]."</span><br>";}
+						if ($showkey) {echo "<span class='key' title='GB-Bezirk-Schl&uuml;ssel'>".$rowbs["bezirk"]."</span><br>";}
 						echo $beznam."</td>"
 						."\n\t\t\t\t<td title='Grundbuch-Blatt'><span class='wichtig'>".$blatt."</span></td>"
@@ -275,6 +294,6 @@
 				echo "\n\t\t<td>"; // 4
 					echo "\n\t\t\t<p class='nwlink noprint'>";
-					// Bestand
-						if ($showkey) {echo "<span class='key'>".$blattkeyber."</span> ";}
+					//	Bestand
+						if ($showkey) {echo "<span class='key' title='Blattart'>(".$blattkeyber.")</span> ";}
 						$url="alkisbestnw.php?gkz=".$gkz."&amp;gmlid=".$gbgml;
 						if ($showkey) {$url.="&amp;showkey=j";}
@@ -283,8 +302,8 @@
 							." <img src='ico/GBBlatt_link.png' width='16' height='16' alt=''>"
 						."</a>";
-					// Buchung
+					//	Buchung
 						if ($trtyp === 1) {
 							echo "<br>";
-							if ($showkey) {echo "<span class='key'>".$bartkey."</span> ";}
+							if ($showkey) {echo "<span class='key' title='Buchungsart'>(".$bartkey.")</span> ";}
 							$url="alkisgsnw.php?gkz=".$gkz."&amp;gmlid=".$hgml;
 							if ($showkey) {$url.="&amp;showkey=j";}
@@ -305,5 +324,5 @@
 	pg_free_result($resbs);
 	
-	//if ($debug > 1) {echo "\n<p class='dbg'>Ende function buchung_anzg(), Return = ". $gezeigt ."</p>";}
+	//if ($dbg > 1) {echo "\n<p class='dbg'>Ende function buchung_anzg(), Return = ". $gezeigt ."</p>";}
 	
 	return $gezeigt; // 1 wenn eine Buchung ausgegeben wurde
@@ -318,5 +337,5 @@
 	//  $gml_fs: GML-ID des FlurstÃŒcke (nur bei erstem Aufruf in einem FS-Nachweis notwendig)
 	//	$gsanfrd: In einem GS-Nachw. die GML-ID der in de URL angeforderten Buchungsstelle (-> Hervorhebung)
-	global $debug, $gezeigt;
+	global $dbg, $gezeigt;
 
 	// sh=Buchungstelle herrschend >(Recht)an> sd=Buchungstelle dienend >istBestandteilVon> BLATT -> Bezirk
@@ -332,5 +351,5 @@
 	if (!$resber) {
 		echo "\n<p class='err'>Fehler bei 'berechtigte Buchungsstellen'.</p>";
-		if ($debug > 2) {echo "\n<p class='dbg'>SQL=<br>".htmlentities(str_replace("$1", "'".$gmls."'", $sql), ENT_QUOTES, "UTF-8")."</p>";}
+		if ($dbg > 2) {echo "\n<p class='dbg'>SQL=<br>".htmlentities(str_replace("$1", "'".$gmls."'", $sql), ENT_QUOTES, "UTF-8")."</p>";}
 	}
 	$an=0;
@@ -370,15 +389,146 @@
 }
 
-function bnw_fsdaten($lfdnr, $gml_bs, $ba, $anteil, $bvnraus, $bartkey, $bartstory) {
-/*	Bestandsnachweis - Flurstuecksdaten
-	Die Tabellenzeilen mit den Flurstuecksdaten zu EINER Buchungsstelle im Bestandsnachweis ausgeben.
-	Die Funktion wird je einmal aufgerufen fÃŒr die Buchungen direkt auf dem GB (Normalfall).
-	Weiterere Aufrufe ggf. bei Erbbaurecht fÃŒr die mit "an" verknuepften Buchungsstellen.
-	Tabellenkopf wird im aufrufenden Programm ausgegeben. */
-	global $debug, $gkz, $showkey, $filtkreis, $filtgem, $trclass;
-
-	// F L U R S T U E C K
+function bnw_bszeile_h() {
+/*	Bestandsnachweis - Buchungs-Stellen-Zeile ausgeben - herrschend.
+	Die GB-Daten hierzu stehen bereits im Kopf und bleiben in der Tab. leer */
+	global $dbg, $gkz, $showkey, $trclass, $lfdnr, $bartkey, $bart, $bartstory, $anteil;
+
+	$bvnr=str_pad($lfdnr, 4, "0", STR_PAD_LEFT);
+	echo "\n<tr class='".$trclass."'>"
+	."\n\t<td id='bvnr".$bvnr."'><span class='wichtig'>".$bvnr."</span></td>" // Sprungmarke=BVNR auf dem GB-Blatt
+	."\n\t<td class='dien' title='".$bartstory."'>";
+	if ($showkey) {echo "<span class='key'>".$bartkey."</span> ";}
+	echo $bart."</td>"
+	."\n\t<td class='dien'>".$anteil."</td>"
+	."\n\t<td>&nbsp;</td>"
+	."\n\t<td>&nbsp;</td>"
+	."\n\t<td>&nbsp;</td>"
+	."\n\t<td>&nbsp;</td>"
+	."\n\t<td>&nbsp;</td>\n</tr>";
+}
+
+function bnw_bszeile_d($bezkey, $beznam, $blatt, $blattartkey, $blattart, $lfdnran, $gbgml, $gml_bsan, $ebene, $und) {
+/*	Bestandsnachweis - Buchungsstellen-Zeile ausgeben - dienend
+	Eine Folge-Zeile fÃŒr eine dienende Buchung ausgeben. */
+	global $gkz, $showkey, $trclass, $bartkey, $bart, $bartstory, $anteil;
+
+	$bvnr=str_pad($lfdnran, 4, "0", STR_PAD_LEFT);
+	$filler=str_repeat("&nbsp;", $ebene - 2); // 3 und 4 EinrÃŒcken
+	if ($und){$filler.="und ";}; // Unterscheidung Hierarchie (Ebene wechselt) von Liste (gleiche Ebene)
+	echo "\n<tr class='".$trclass."'>"
+	."\n\t<td title='Ebene ".$ebene."'>".$filler."an</td>"
+	."\n\t<td class='dien' title='".$bartstory."'>"; // Sp.2 Buchungsart
+	if ($showkey) {echo "<span class='key'>".$bartkey."</span> ";}
+	echo $bart."</td>"
+	."\n\t<td class='dien'>".$anteil."</td>"; // Sp.3 Anteil
+
+	// Sp.4 GB-Bezirk
+	echo "\n\t<td class='dien' title='Grundbuch-Bezirk'>"; 
+		if ($showkey) {echo "<span class='key'>".$bezkey."</span> ";}
+		echo htmlentities($beznam, ENT_QUOTES, "UTF-8")
+	."</td>"
+	."\n\t<td class='dien' title='".$blattart."'>".$blatt."</td>" // Sp.5
+	."\n\t<td class='dien' title='Bestandsverzeichnis-Nummer'>".$bvnr."</td>" // Sp.6
+	."\n\t<td class='dien'></td>"; 
+
+	echo "\n\t<td>\n\t\t<p class='nwlink noprint'>"; // Sp.8 Link
+
+	// Link Bestand Blatt
+	if ($showkey) {echo "<span class='key'>".$blattartkey."</span>";} // Blatt-Art
+	echo "\n\t\t\t<a href='alkisbestnw.php?gkz=".$gkz."&amp;gmlid=".$gbgml;
+		if ($showkey) {echo "&amp;showkey=j";}
+		echo "#bvnr".$lfdnran."' title='Zum Grundbuchnachweis des dienenden Blattes'>".$blattart
+	." <img src='ico/GBBlatt_link.png' width='16' height='16' alt=''></a>";
+
+	if ($bartkey < 2000){
+		// Link Buchung BVNR nur fÃŒr GrundstÃŒck usw.
+		echo "<br>\n\t\t\t<a href='alkisgsnw.php?gkz=".$gkz."&amp;gmlid=".$gml_bsan;
+		if ($showkey) {echo "&amp;showkey=j";}
+		echo "' title='Grundst&uuml;cksnachweis'>Buchung <img src='ico/Grundstueck_Link.png' width='16' height='16' alt=''></a>";	
+	}
+
+	echo "\n\t\t</p>"
+	."\n\t</td>\n</tr>";
+}
+
+function bnw_bsdaten($gml_h, $ebene) {
+/*	Bestandsnachweis - Buchungsstellen-Daten
+	"dienende" Buchungsstellen suchen. Miteigentumsanteil, Erbbaurecht usw. 
+	Return: gml_id der dienenden Buchungsstelle wenn gefunden? Sonst Leerstring */
+	global $dbg, $bartkey, $bart, $bartstory, $anteil;
+
+//	dann "dienende" Buchungsstellen
+//  sh=herrschend          sd=dienend
+//  ax_buchungsstelle >zu> ax_buchungsstelle (des gleichen Blattes) 
+//  ax_buchungsstelle >an> ax_buchungsstelle (anderes Blatt, z.B Erbbaurecht an)
+//	- "zu" kommt in der Praxis (NRW) nicht vor, wird hier nicht berÃŒcksichtigt
+
+	if ($ebene > 5) {echo "\n<p class='err'>UngewÃ¶hnlich tiefe Schachtelung ".$ebene." der Buchungs-Stellen.</p>";}
+
+	$sql ="SELECT sd.gml_id, sd.buchungsart, sd.zaehler, sd.nenner, sd.laufendenummer AS lfd, sd.beschreibungdesumfangsderbuchung AS udb, "
+	."sd.nummerimaufteilungsplan AS nrap, sd.beschreibungdessondereigentums AS sond, "
+	."wb.beschreibung AS bart, wb.dokumentation, "
+	."b.gml_id as gbgml, b.bezirk, b.buchungsblattnummermitbuchstabenerweiterung AS blatt, b.blattart, "
+	."bb.beschreibung AS blattartv, z.bezeichnung AS beznam "
+	."FROM ax_buchungsstelle sh "
+	."JOIN ax_buchungsstelle sd ON sd.gml_id=ANY(sh.an) "
+	."JOIN ax_buchungsblatt b ON b.gml_id=sd.istbestandteilvon "	
+	."LEFT JOIN ax_buchungsart_buchungsstelle wb ON sd.buchungsart = wb.wert "
+	."LEFT JOIN ax_buchungsblattbezirk z ON b.land=z.land AND b.bezirk=z.bezirk ".UnqKatAmt("b","z")
+	."LEFT JOIN ax_blattart_buchungsblatt bb ON b.blattart = bb.wert "
+	."WHERE sh.gml_id= $1 AND sh.endet IS NULL AND sd.endet IS NULL AND b.endet IS NULL AND z.endet IS NULL "
+	."ORDER BY sd.laufendenummer;";
+	$v=array($gml_h); // gml_id "herrschende" B-Stelle
+	$resan=pg_prepare("", $sql);
+	$resan=pg_execute("", $v);
+	if (!$resan) {
+		echo "\n<p class='err'>Fehler bei 'dienende Buchungsstelle'.</p>";
+		if ($dbg > 2) {echo "\n<p class='dbg'>SQL=<br>".htmlentities(str_replace("$1", "'".$gml_bs."'", $sql), ENT_QUOTES, "UTF-8")."</p>";}
+	}
+	$zeianz=pg_num_rows($resan); // Zeilen-Anzahl = Returnwert
+	//if ($dbg > 0) {echo "\n<p class='dbg'>Auf Ebene ".$ebene.": Anzahl diennende Buchungs-Stellen = ".$zeianz.".</p>";}
+	$und = false; // mehrfaches "Recht an" auf gleicher Ebene
+	while($row= pg_fetch_assoc($resan)) {
+		$gml_bsan=$row["gml_id"];	// id der dien. BS
+		$blatt=ltrim($row["blatt"], "0");		
+
+		// als Global-Var zur Sub-Function:
+		$bartkey=$row["buchungsart"];	
+		$bart=$row["bart"]; // Buchungsart, entschlÃŒsselt
+		$bartstory=htmlentities($row["dokumentation"], ENT_QUOTES, "UTF-8");
+		if ($row["zaehler"] == "") {$anteil = "";} 
+		else {$anteil = $row["zaehler"]."/".$row["nenner"];}
+
+		// Zeile ausgeben Buchungsstelle dienend 
+		bnw_bszeile_d($row["bezirk"], $row["beznam"], $blatt, $row["blattart"], $row["blattartv"], $row["lfd"], $row["gbgml"], $gml_bsan, $ebene, $und);
+		$und = true;
+		if ($row["nrap"] != "") { // Nr im Auft.Plan
+			echo "\n<tr>\n\t<td colspan=3></td><td class='nrap' colspan=4>Nummer <span class='wichtig'>".$row["nrap"]."</span> im Aufteilungsplan.</td><td></td>\n</tr>";
+		}
+		if ($row["sond"] != "") { // Sondereigentumsbeschreibung
+			echo "\n<tr>\n\t<td></td><td class='sond' colspan=6 title='Sondereigentums-Beschreibung'>Verbunden mit dem Sondereigentum an: ".$row["sond"]."</td><td></td>\n</tr>";
+		}
+
+		// Rekursiver Aufruf der gleichen Function, weitere Ebene dienend?
+		$tiefer = bnw_bsdaten($gml_bsan, ($ebene + 1));
+		If ($tiefer == 0) {  // Wenn nicht, dann kann es FlurstÃŒcke dazu geben
+			$fscnt= bnw_fsdaten($gml_bsan, false); // FlurstÃŒcksdaten
+		}
+	}
+	pg_free_result($resan);
+	return $zeianz;
+}
+
+function bnw_fsdaten($gml_bs, $mit_buchung_link) {
+/*	Bestandsnachweis - FlurstÃŒcksdaten
+	Die Tabellenzeilen mit den FlurstÃŒcksdaten zu EINER Buchungsstelle im Bestandsnachweis ausgeben.
+	Die Funktion wird entweder aufgerufen fÃŒr die Buchungen direkt auf dem GB (Normalfall)
+	oder bei Erbbaurecht fÃŒr die mit "an" verknÃŒpften Buchungsstellen der untersten Ebene (dienende Buchung).
+	Der Tabellenkopf wird im aufrufenden Programm ausgegeben. 
+	Return: Anzahl der ausgegebenen FlurstÃŒcke */
+	global $dbg, $gkz, $showkey, $filtkreis, $filtgem, $trclass, $katAmtMix, $lfdnr, $altlfdnr, $bartkey, $bart, $bartstory, $anteil;
+
 	$sql="SELECT g.gemarkungsnummer, g.bezeichnung, f.gml_id, f.flurnummer, f.zaehler, f.nenner, f.amtlicheflaeche "
-	."FROM ax_flurstueck f LEFT JOIN ax_gemarkung g ON f.land=g.land AND f.gemarkungsnummer=g.gemarkungsnummer "
+	."FROM ax_flurstueck f LEFT JOIN ax_gemarkung g ON f.land=g.land AND f.gemarkungsnummer=g.gemarkungsnummer ".UnqKatAmt("f","g")
 	."WHERE f.endet IS NULL AND g.endet IS NULL AND f.istgebucht = $1 ";
 	if ($filtgem === '') { // ungefiltert
@@ -392,14 +542,6 @@
 	$resf = pg_execute("", $v);
 	if (!$resf) {echo "\n<p class='err'>Fehler bei Flurst&uuml;ck</p>";}
-
-	if($bvnraus) { // nur bei direkten Buchungen die lfdNr ausgeben
-		$bvnr=str_pad($lfdnr, 4, "0", STR_PAD_LEFT);
-	} else {
-		$bvnr="";
-	}
-	$altbvnr=""; // ++ besser mit "$j === 0" steuern?
-	$j=0;
+	$zeianz=pg_num_rows($resf);
 	while($rowf = pg_fetch_assoc($resf)) {
-		$flur= $rowf["flurnummer"];
 		$fskenn=$rowf["zaehler"];
 		if ($rowf["nenner"] != "") { // Bruch
@@ -409,52 +551,47 @@
 
 		echo "\n<tr class='".$trclass."'>"; // eine Zeile je Flurstueck
-			// Sp. 1-3 der Tab. aus Buchungsstelle, nicht aus FS
-			if($bvnr === $altbvnr) { // gleiches Grundstueck, leer lassen
-				echo "\n\t<td>&nbsp;</td>"
-				."\n\t<td>&nbsp;</td>"
-				."\n\t<td>&nbsp;</td>";
-			} else { // Sprungmarke, BVNR
-				echo "\n\t<td id='bvnr".$bvnr."'>"; // Sprungmarke
-				//	echo "\n\t\t<a id='bvnr".$bvnr."'></a>";
-					echo "<span class='wichtig'>".$bvnr."</span>"
-				."\n\t</td>";
-
-				echo "\n\t<td title ='".$bartstory."'>"; // Buchungsart 
-					if ($showkey) {echo "<span class='key'>".$bartkey."</span>&nbsp;";} // Schluessel
-					echo $ba; // entschluesselt
-				echo "</td>"
-				."\n\t<td>&nbsp;</td>"; // Anteil
-			}
-
-			// Sp. 4-7 aus Flurstueck
-			echo "\n\t<td>";
-			if ($showkey) {echo "<span class='key'>".$rowf["gemarkungsnummer"]."</span> ";}
-			echo $rowf["bezeichnung"]."</td>"
-			."\n\t<td>".$flur."</td>"
-			."\n\t<td class='fsnr'><span class='wichtig'>".$fskenn."</span>"
-			."</td>"
-			."\n\t<td class='flag'>".$flae."</td>"; // "width" hier (flaG) erweiterbar, weil in andere Zeile die Buchungsart steht 
-			echo "\n\t<td>\n\t\t<p class='nwlink noprint'>";
-		//	if($bvnr != $altbvnr) {
-			if($j === 0) {
-				echo "\n\t\t\t<a href='alkisgsnw.php?gkz=".$gkz."&amp;gmlid=".$gml_bs;
-					if ($showkey) {echo "&amp;showkey=j";}
-					echo "' title='Grundst&uuml;cksnachweis'>Buchung "
-					."<img src='ico/Grundstueck_Link.png' width='16' height='16' alt=''>"
-				."</a>";
-
-			}
-				echo "\n\t\t\t<a href='alkisfsnw.php?gkz=".$gkz."&amp;gmlid=".$rowf["gml_id"]."&amp;eig=n";
-					if ($showkey)   {echo "&amp;showkey=j";}
-					echo "' title='Flurst&uuml;cksnachweis'>Flurst&uuml;ck "
-					."<img src='ico/Flurstueck_Link.png' width='16' height='16' alt=''>"
-				."</a>"
-			."\n\t\t</p>\n\t</td>"
-		."\n</tr>";
-		$altbvnr=$bvnr;
-		$j++;
+		
+		// Sp. 1-3 der Tab. Daten aus Buchungsstelle, nicht aus FS
+		if($lfdnr === $altlfdnr) { // gleiches GrundstÃŒck, leer lassen
+			echo "\n\t<td>&nbsp;</td>"
+			."\n\t<td>&nbsp;</td>"
+			."\n\t<td>&nbsp;</td>";
+		} else { // Sprungmarke, BVNR
+			$bvnr=str_pad($lfdnr, 4, "0", STR_PAD_LEFT);
+			echo "\n\t<td id='bvnr".$bvnr."'>"; // Sprungmarke
+				echo "<span class='wichtig'>".$bvnr."</span>"
+			."\n\t</td>";
+			echo "\n\t<td title ='".$bartstory."'>"; // Buchungsart 
+				if ($showkey) {echo "<span class='key'>".$bartkey."</span>&nbsp;";}
+				echo $bart;
+			echo "</td>"
+			."\n\t<td>&nbsp;</td>"; // Anteil
+			$altlfdnr=$lfdnr;
+		}
+
+		// Sp. 4-7 aus FlurstÃŒck
+		echo "\n\t<td>";
+		if ($showkey) {echo "<span class='key'>".$rowf["gemarkungsnummer"]."</span> ";}
+		echo $rowf["bezeichnung"]."</td>"
+		."\n\t<td>".$rowf["flurnummer"]."</td>\n\t<td class='fsnr'><span class='wichtig'>".$fskenn."</span></td>"
+		."\n\t<td class='fla'>".$flae."</td>";
+		echo "\n\t<td>\n\t\t<p class='nwlink noprint'>";
+
+		// Buchung BVNR
+		If ($mit_buchung_link == true) { // nur bei GrundstÃŒck
+			echo "\n\t\t\t<a href='alkisgsnw.php?gkz=".$gkz."&amp;gmlid=".$gml_bs;
+			if ($showkey) {echo "&amp;showkey=j";}
+			echo "' title='Grundst&uuml;cksnachweis'>Buchung <img src='ico/Grundstueck_Link.png' width='16' height='16' alt=''></a>&nbsp;";			
+			$mit_buchung_link = false; // nur in erster Zeile
+		}
+		// Flurstk.
+		echo "\n\t\t\t<a href='alkisfsnw.php?gkz=".$gkz."&amp;gmlid=".$rowf["gml_id"]."&amp;eig=n";
+			if ($showkey)   {echo "&amp;showkey=j";}
+			echo "' title='Flurst&uuml;cksnachweis'>Flurst&uuml;ck "
+			."<img src='ico/Flurstueck_Link.png' width='16' height='16' alt=''></a>"
+		."\n\t\t</p>\n\t</td>\n</tr>";
 	}
 	pg_free_result($resf);
-	return $j;
+	return $zeianz;
 }
 
@@ -469,5 +606,5 @@
 	// Schleife 1: N a m e n s n u m m e r
 	// Beziehung: ax_namensnummer >istBestandteilVon> ax_buchungsblatt
-	global $debug, $gkz, $showkey;
+	global $dbg, $gkz, $showkey;
 
 	if ($lnkclass == "") {
@@ -484,6 +621,5 @@
 	."LEFT JOIN ax_eigentuemerart_namensnummer we ON n.eigentuemerart = we.wert "
 	."WHERE n.istbestandteilvon= $1 AND n.endet IS NULL ORDER BY n.laufendenummernachdin1421;";
-	// +++	LEFT JOIN bis ax_Person statt Person als Schleife zu holen, 
-	//		VerknÃŒpfungsfeld "benennt" ist leer bei "Beschrieb der Rechtsgemeinschaft".
+	// VerknÃŒpfungsfeld "benennt" ist leer bei "Beschrieb der Rechtsgemeinschaft".
 
 	$v = array($gmlid); // GB-Blatt
@@ -493,5 +629,5 @@
 	if (!$resn) {
 		echo "\n<p class='err'>Fehler bei Eigent&uuml;mer</p>"; // kein Fehler bei Blattarten > 1000
-		//if ($debug > 2) {echo "\n<p class='dbg'>SQL=<br>".str_replace("$1", "'".$gmlid."'", $sqln )."</p>";}
+		//if ($dbg > 2) {echo "\n<p class='dbg'>SQL=<br>".str_replace("$1", "'".$gmlid."'", $sqln )."</p>";}
 	}
 
@@ -501,4 +637,8 @@
 		$namnum=kurz_namnr($rown["lfd"]);
 		$rechtsg=$rown["adr"];
+		$eiartkey=$rown["eigentuemerart"]; // Key
+		$eiart=$rown["eiartv"]; // Value
+	//	if ($dbg > 1) {echo "\n<p class='dbg'>Eigent&uuml:merart = '".$eiartkey."' = '".$eiart."'</p>";}
+
 		echo "\n\t<tr>";
 			if($n === 0) { // erste EigentÃŒmer-Zeile zu einer Buchung
@@ -527,5 +667,4 @@
 
 		// Schleife 2: P e r s o n
-		// +++ bei SQL Namensnummer oben gleich mit JOIN dazu holen, statt dieser Schleife
 		// Beziehung: ax_person  <benennt<  ax_namensnummer
 		$sqlp="SELECT nachnameoderfirma, vorname, geburtsname, to_char(cast(geburtsdatum AS date),'DD.MM.YYYY') AS geburtsdatum, namensbestandteil, akademischergrad "
@@ -537,5 +676,5 @@
 		if (!$resp) {
 			echo "\n\t<p class='err'>Fehler bei Person</p>";
-			if ($debug > 2) {echo "\n<p class='err'>SQL=<br>".str_replace("$1", "'".$gmlpers."'", $sqlp)."</p>";}
+			if ($dbg > 2) {echo "\n<p class='err'>SQL=<br>".str_replace("$1", "'".$gmlpers."'", $sqlp)."</p>";}
 		}
 
@@ -550,15 +689,13 @@
 			if ($rowp["geburtsname"] != "") {$diePerson.=", geb. ".$rowp["geburtsname"];}
 			$diePerson=htmlentities($diePerson, ENT_QUOTES, "UTF-8"); // Umlaute
-			$eiartkey=$rown["eigentuemerart"]; // Key
-			$eiart=$rown["eiartv"]; // Value
 
 			echo "\n\t\t\t<p class='geig' title='Eigent&uuml;merart: ".$eiart."'>".$diePerson."</p>\n\t\t</td>"; // 3 - Person in Sp.3 hinter NamNum (Sp.2)
 			echo "\n\t\t<td>\n\t\t\t<p class='nwlink noprint'>"; // 4
-				if ($showkey AND $eiartkey != '') {echo "<span class='key' title='Eigent&uuml;merart'>".$eiartkey."</span> ";}
+				if ($showkey AND $eiartkey != '') {echo "<span class='key' title='Eigent&uuml;merart'>(".$eiartkey.")</span> ";}
 				echo "\n\t\t\t\t<a href='".$lnkvor."alkisnamstruk.php?gkz=".$gkz."&amp;gmlid=".$gmlpers;
 				if ($showkey) {echo "&amp;showkey=j";}
-				if ($eiartkey === "") {$eiart="Eigent&uuml;mer" ;} // Default. Ersatz-Text, wenn nicht gefÃŒllt
+				if ($eiartkey == "") {$eiart="Eigent&uuml;mer" ;} // Default. Ersatz-Text, wenn nicht gefÃŒllt
 				echo $lnknach."' title='vollst&auml;ndiger Name und Adresse eines Eigent&uuml;mers'>".$eiart
-				." <img src='ico/Eigentuemer.png' width='16' height='16' alt=''></a>\n\t\t\t</p>"
+				." \n\t\t\t\t\t<img src='ico/Eigentuemer.png' width='16' height='16' alt=''>\n\t\t\t\t</a>\n\t\t\t</p>"
 			."\n\t\t</td>" // 4
 			."\n\t</tr>";
@@ -573,5 +710,5 @@
 				if (!$resa) {
 					echo "\n\t<p class='err'>Fehler bei Adressen</p>";
-					if ($debug > 2) {echo "\n<p class='err'>SQL=<br>".str_replace("$1", "'".$gmlpers."'", $sqla)."</p>";}
+					if ($dbg > 2) {echo "\n<p class='err'>SQL=<br>".str_replace("$1", "'".$gmlpers."'", $sqla)."</p>";}
 				}
 				$j=0;
@@ -628,7 +765,6 @@
 
 		if ($i === 0) { // KEINE Person. benennt ist leer. Das kommt vor hinter der Zeile "Erbengemeinschaft" und ist dann KEIN Fehler
-			if ($rechtsg === 9999) {
-				if ($debug > 1) {echo "\n\t\t\t<p class='dbg'>Rechtsgemeinschaft = '".$rechtsg."'</p>";}
-			} else {
+			if ($dbg > 1) {echo "\n\t\t\t<p class='dbg'>Rechtsgemeinschaft = '".$rechtsg."'</p>";}
+			if ($rechtsg !== '9999') {
 				echo "\n<p class='err'>(Die Person mit der ID '".$gmlpers."' fehlt im Datenbestand)</p>";
 			}
@@ -646,5 +782,5 @@
 	// Dient dazu, SchlÃŒssel-ARRAYs auflÃ¶sen ohne die Zeile im JOIN mehrfach aufzulisten
 	// Anwendung: FS-Nachweis BodenschÃ€tzung
-	global $debug;
+	global $dbg;
 
 	if ($bez === 'e') {$tabelle = 'ax_entstehungsartoderklimastufewasserverhaeltnisse_bodensc';} 
@@ -657,5 +793,5 @@
 	if (!$res) {
 		echo "\n<p class='err'>Fehler bei Werteliste.</p>";
-		if ($debug > 2) {echo "\n<p class='dbg'>SQL=<br>".htmlentities($sql, ENT_QUOTES, "UTF-8")."</p>";}
+		if ($dbg > 2) {echo "\n<p class='dbg'>SQL=<br>".htmlentities($sql, ENT_QUOTES, "UTF-8")."</p>";}
 		return;
 	}
@@ -668,5 +804,5 @@
 	if ($i === 0) {
 		echo "(kein Treffer)";
-		if ($debug > 2) {echo "\n<p class='dbg'>SQL=<br>".htmlentities($sql, ENT_QUOTES, "UTF-8")."</p>";}
+		if ($dbg > 2) {echo "\n<p class='dbg'>SQL=<br>".htmlentities($sql, ENT_QUOTES, "UTF-8")."</p>";}
 	}
 	return;
@@ -676,7 +812,7 @@
 // Tabelle im Kopf von FlurstÃŒck und FS-Historie. 2 Z./Sp. Entstehung/FortfÃŒhrung
 // Parameter: Die DB-Spalten "zeitpunktderentstehung", "zeigtaufexternes_art" und "zeigtaufexternes_name"
-	global $debug, $showkey;
-
-//	if ($debug > 2) {echo "<p class='dbg'>function fortfuehrungen<br>1: ".$dbzeart."<br>2: ".$dbzename."</p>";}
+	global $dbg, $showkey;
+
+//	if ($dbg > 2) {echo "<p class='dbg'>function fortfuehrungen<br>1: ".$dbzeart."<br>2: ".$dbzename."</p>";}
  
 	echo "\n\t<table class='fsd'>" // FS-Daten 2 Spalten
