VergleichsansichtMieteToJsonDbFunctions.java 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. package com.tsystems.diwo.business.queries;
  2. import com.fasterxml.jackson.core.JsonProcessingException;
  3. import com.tsystems.common.InwoLogger;
  4. import com.tsystems.common.model.db.interfaces.IInwoDBCall;
  5. import java.math.BigDecimal;
  6. import java.sql.ResultSet;
  7. import java.sql.SQLException;
  8. import java.sql.Types;
  9. import java.util.ArrayList;
  10. import java.util.Collections;
  11. import java.util.Date;
  12. import java.util.LinkedHashMap;
  13. import java.util.List;
  14. import java.util.Map;
  15. import oracle.jbo.JboException;
  16. public class VergleichsansichtMieteToJsonDbFunctions extends VergleichsansichtBaseDbFunctions {
  17. private static final InwoLogger LOG = InwoLogger.createInwoLogger( VergleichsansichtMieteToJsonDbFunctions.class );
  18. /* ============================================================
  19. ÖFFENTLICHE EINSTIEGE (Root: "stammakte" -> vorgaenge[])
  20. ============================================================ */
  21. public static String buildJsonAktuellerVorgang ( IInwoDBCall dbCall, Integer sakId, Integer lfdnr,
  22. Integer konnr ) throws SQLException, JsonProcessingException {
  23. Map<String, Object> stammakte = fetchStammakte( dbCall, sakId );
  24. if ( stammakte == null ) {
  25. stammakte = new LinkedHashMap<>();
  26. }
  27. Map<String, Object> stammvorgang = fetchStammvorgang( dbCall, sakId, lfdnr );
  28. if ( stammvorgang == null ) {
  29. stammvorgang = new LinkedHashMap<>();
  30. }
  31. Date eingang = fetchEingangsdatum( dbCall, sakId, lfdnr );
  32. // Hole bez und wognr aus t_akten für fetchRecht
  33. Map<String, Integer> aktenData = fetchBezWognrFromAkten( dbCall, sakId );
  34. if ( aktenData == null || aktenData.get( "bez" ) == null || aktenData.get( "wognr" ) == null ) {
  35. throw new JboException( "Fehler: Konnte BEZ/WOGNR für SAK_ID " + sakId + " nicht ermitteln" );
  36. }
  37. String recht = fetchRecht( dbCall, aktenData.get( "bez" ), aktenData.get( "wognr" ), lfdnr );
  38. List<Map<String, Object>> zeitraeume =
  39. fetchZeitraeumeUndDetails( dbCall, aktenData.get( "bez" ), aktenData.get( "wognr" ), lfdnr, eingang, recht,
  40. /*onlyKonnr*/konnr );
  41. if ( zeitraeume == null ) {
  42. zeitraeume = new ArrayList<>();
  43. }
  44. Map<String, Object> vorgangObj = new LinkedHashMap<>();
  45. vorgangObj.put( "stammvorgang", stammvorgang );
  46. vorgangObj.put( "zeitraeume", zeitraeume );
  47. List<Map<String, Object>> vorgaenge = new ArrayList<>();
  48. vorgaenge.add( vorgangObj );
  49. stammakte.put( "vorgaenge", vorgaenge );
  50. String result = om.writeValueAsString( Collections.singletonMap( "stammakte", stammakte ) );
  51. LOG.finest( "Resulting JSON: " + result );
  52. // Close database call at the very end after all queries are completed
  53. dbCall.closeQuery();
  54. return result;
  55. }
  56. /** Alle anderen Vorgänge (≠ lfdnr) + alle deren Zeiträume -> {"stammakte":{..., "vorgaenge":[{...}, ...]}} */
  57. public static String buildJsonAndereVorgaenge ( IInwoDBCall dbCall, Integer sakId,
  58. Integer lfdnr ) throws SQLException, JsonProcessingException {
  59. Map<String, Object> stammakte = fetchStammakte( dbCall, sakId );
  60. if ( stammakte == null ) {
  61. stammakte = new LinkedHashMap<>();
  62. }
  63. List<Integer> andere = fetchAndereLfdnr( dbCall, sakId, lfdnr );
  64. List<Map<String, Object>> vorgaenge = new ArrayList<>();
  65. // Hole bez und wognr aus t_akten für fetchRecht
  66. Map<String, Integer> aktenData = fetchBezWognrFromAkten( dbCall, sakId );
  67. if ( aktenData == null || aktenData.get( "bez" ) == null || aktenData.get( "wognr" ) == null ) {
  68. throw new JboException( "Fehler: Konnte BEZ/WOGNR für SAK_ID " + sakId + " nicht ermitteln" );
  69. }
  70. for ( Integer otherLfdnr : andere ) {
  71. Map<String, Object> stammvorgang = fetchStammvorgang( dbCall, sakId, otherLfdnr );
  72. if ( stammvorgang == null ) {
  73. stammvorgang = new LinkedHashMap<>();
  74. }
  75. Date eingang = fetchEingangsdatum( dbCall, sakId, otherLfdnr );
  76. String recht = fetchRecht( dbCall, aktenData.get( "bez" ), aktenData.get( "wognr" ), otherLfdnr );
  77. List<Map<String, Object>> zeitraeume =
  78. fetchZeitraeumeUndDetails( dbCall, aktenData.get( "bez" ), aktenData.get( "wognr" ), otherLfdnr,
  79. eingang, recht, /*onlyKonnr*/null );
  80. if ( zeitraeume == null ) {
  81. zeitraeume = new ArrayList<>();
  82. }
  83. Map<String, Object> vorgangObj = new LinkedHashMap<>();
  84. vorgangObj.put( "stammvorgang", stammvorgang );
  85. vorgangObj.put( "zeitraeume", zeitraeume );
  86. vorgaenge.add( vorgangObj );
  87. }
  88. stammakte.put( "vorgaenge", vorgaenge );
  89. String result = om.writeValueAsString( Collections.singletonMap( "stammakte", stammakte ) );
  90. LOG.finest( "Resulting JSON: " + result );
  91. // Close database call at the very end after all queries are completed
  92. dbCall.closeQuery();
  93. return result;
  94. }
  95. /* ===========================
  96. Vorgang / Listen / Felder
  97. =========================== */
  98. private static Date fetchEingangsdatum ( IInwoDBCall dbCall, Integer sakId, Integer lfdnr ) throws SQLException {
  99. String q = "SELECT EING_DAT FROM T_STAMMVORGAENGE WHERE SAK_ID = :sak_id AND LFDNR = :lfdnr";
  100. dbCall.query( q );
  101. dbCall.in( "sak_id", sakId, Types.INTEGER );
  102. dbCall.in( "lfdnr", lfdnr, Types.INTEGER );
  103. ResultSet rs = dbCall.executeQuery( true );
  104. if ( rs.next() )
  105. return rs.getDate( "EING_DAT" );
  106. return null;
  107. }
  108. /** Holt RECHT; Fallback auf SGESETZESFASSUNG (String). */
  109. private static String fetchRecht ( IInwoDBCall dbCall, Integer bez, Integer wognr,
  110. Integer lfdnr ) throws SQLException {
  111. String q = "SELECT RECHT " + "FROM T_ANTRAEGE WHERE WOGNR = :wognr AND BEZ = :bez AND LFDNR = :lfdnr";
  112. dbCall.query( q );
  113. dbCall.in( "wognr", wognr, Types.INTEGER );
  114. dbCall.in( "bez", bez, Types.INTEGER );
  115. dbCall.in( "lfdnr", lfdnr, Types.INTEGER );
  116. ResultSet rs = dbCall.executeQuery( true );
  117. if ( rs.next() ) {
  118. String recht = nullTrim( rs.getString( "RECHT" ) );
  119. return recht;
  120. }
  121. return null;
  122. }
  123. /* ===========================
  124. Zeiträume + Details
  125. =========================== */
  126. /**
  127. * Lädt Zeiträume für einen Vorgang.
  128. * - onlyKonnr != null -> nur dieser KONNR (aktueller Vorgang)
  129. * - onlyKonnr == null -> alle Zeiträume (andere Vorgänge)
  130. */
  131. private static List<Map<String, Object>> fetchZeitraeumeUndDetails ( IInwoDBCall dbCall, Integer bez, Integer wognr,
  132. Integer lfdnr, Date eingang, String recht,
  133. Integer onlyKonnr ) throws SQLException {
  134. LOG.finest( "fetchZeitraeumeUndDetails BEZ: " + bez + " - WOGNR: " + wognr + " - LFDNR: " + lfdnr +
  135. " - onlyKonnr: " + onlyKonnr );
  136. String base =
  137. "SELECT TO_CHAR(k.KONNR) AS zeitraum_id, " + " TO_CHAR(k.BEGINN_DAT, 'YYYY-MM-DD') AS beginn, " +
  138. " TO_CHAR(k.ENDE_DAT, 'YYYY-MM-DD') AS ende, " +
  139. " k.MIETE AS miete_ref_id, k.AUSSTATTUNG AS ausstattung_ref_id " + "FROM T_KONSTELLATIONEN k " +
  140. "WHERE k.AN_WOGNR = :wognr AND k.AN_BEZ = :bez AND k.AN_LFDNR = :lfdnr ";
  141. String filter = ( onlyKonnr != null ) ? "AND k.KONNR = :konnr " : "";
  142. String order = "ORDER BY k.BEGINN_DAT NULLS FIRST, k.KONNR";
  143. String q = base + filter + order;
  144. LOG.finest( "SQL Query: " + q );
  145. LOG.finest( "Parameters - bez: " + bez + ", wognr: " + wognr + ", lfdnr: " + lfdnr + ", konnr: " + onlyKonnr );
  146. dbCall.query( q );
  147. dbCall.in( "wognr", wognr, Types.INTEGER );
  148. dbCall.in( "bez", bez, Types.INTEGER );
  149. dbCall.in( "lfdnr", lfdnr, Types.INTEGER );
  150. if ( onlyKonnr != null )
  151. dbCall.in( "konnr", onlyKonnr, Types.INTEGER );
  152. List<Map<String, Object>> out = new ArrayList<>();
  153. ResultSet rs = dbCall.executeQuery( true );
  154. LOG.finest( "SQL executed, checking for results..." );
  155. int rowCount = 0;
  156. while ( rs.next() ) {
  157. rowCount++;
  158. LOG.finest( "Processing row " + rowCount );
  159. String zeitraumId = rs.getString( "zeitraum_id" );
  160. String beginn = rs.getString( "beginn" );
  161. String ende = rs.getString( "ende" );
  162. Integer mieteId = ( ( BigDecimal ) rs.getObject( "miete_ref_id" ) ).intValue();
  163. Integer ausstId = ( ( BigDecimal ) rs.getObject( "ausstattung_ref_id" ) ).intValue();
  164. Map<String, Object> zr = new LinkedHashMap<>();
  165. zr.put( "id", zeitraumId );
  166. if ( beginn != null )
  167. zr.put( "beginn", beginn );
  168. if ( ende != null )
  169. zr.put( "ende", ende );
  170. Map<String, Object> miete = fetchMiete( dbCall, mieteId, recht );
  171. if ( miete == null ) {
  172. miete = new LinkedHashMap<>();
  173. }
  174. List<Map<String, Object>> untermieter = fetchUntermieter( dbCall, mieteId, recht );
  175. if ( untermieter == null ) {
  176. untermieter = new ArrayList<>();
  177. }
  178. miete.put( "untermieter", untermieter );
  179. List<Map<String, Object>> mitbewohner = fetchMitbewohner( dbCall, mieteId, recht );
  180. if ( mitbewohner == null ) {
  181. mitbewohner = new ArrayList<>();
  182. }
  183. miete.put( "mitbewohner", mitbewohner );
  184. zr.put( "miete", miete );
  185. Map<String, Object> ausstattung = fetchAusstattung( dbCall, ausstId, eingang );
  186. if ( ausstattung == null ) {
  187. ausstattung = new LinkedHashMap<>();
  188. }
  189. zr.put( "ausstattung", ausstattung );
  190. out.add( zr );
  191. }
  192. LOG.finest( "Returning " + out.size() + " zeitraeume" );
  193. return out;
  194. }
  195. /* ===================== Miete inkl. Pauschalen ===================== */
  196. private static Map<String, Object> fetchMiete ( IInwoDBCall dbCall, Integer mieteIdOrNull,
  197. String recht ) throws SQLException {
  198. String q =
  199. "SELECT " + " TO_CHAR(m.ID) AS id, " +
  200. " m.MIETE AS miete, m.MIETE_ALT AS mieteAlt, m.SONST_ZUSCHLAG AS sonstZuschlag, " +
  201. " m.BEITRAG_DRITTER AS beitragDritter, " + " m.HEIZUNG AS heizung, m.HEIZUNG_P AS heizungP_raw, " +
  202. " m.WARMWASSER AS warmwasser, m.WARMWASSER_P AS warmwasserP_raw, " +
  203. " m.MOEBLIERUNG AS moeblierung, m.MOEBLIERUNG_P AS moeblierungP_raw, " +
  204. " m.UMIET_ZUSCHLAG AS umietZuschlag, " +
  205. " m.GEWERBE_ZUSCHLAG AS gewerbeZuschlag, m.GEWERBE_ZUSCHLAG_P AS gewerbeZuschlagP_raw, " +
  206. " m.GEWERBE_FLAECHE AS gewerbeFlaeche, " +
  207. " m.JHRL_FERNWARMW AS jhrlFernwarmw, m.JHRL_FERNWAERME AS jhrlFernwaerme, " +
  208. " m.ANT_MIET_WW AS antMietWw, m.ANT_BRUT_WW AS antBrutWw, m.JHRL_FERN_W_UND_W AS jhrlFernWUndW, " +
  209. " m.LSTG_AUFENTHALT_PERSON AS lstgAufenthaltPerson, " +
  210. " m.SONST_WOG_FAEHIG_BETRAG AS sonstWogFaehigBetrag, m.SONST_WOG_FAEHIG_TEXT AS sonstWogFaehigText, " +
  211. " m.SONST_ZUSCHLAG_BESCHR AS sonstZuschlagBeschr, " +
  212. " m.ENERGIE AS energie, m.ENERGIE_P AS energieP_raw, " +
  213. " m.STELLPLATZ AS stellplatz, m.STELLPLATZ_P AS stellplatzP_raw " +
  214. "FROM T_MIETEN m WHERE m.ID = COALESCE(:miete_id, 1)";
  215. dbCall.query( q );
  216. dbCall.in( "miete_id", mieteIdOrNull, Types.INTEGER );
  217. Map<String, Object> out = new LinkedHashMap<>();
  218. ResultSet rs = dbCall.executeQuery( true );
  219. if ( rs.next() ) {
  220. out.put( "id", "1" ); // Always set miete ID to "1" in JSON output
  221. putNum( out, "miete", rs, "miete" );
  222. putNum( out, "mieteAlt", rs, "mieteAlt" );
  223. putNum( out, "sonstZuschlag", rs, "sonstZuschlag" );
  224. putNum( out, "beitragDritter", rs, "beitragDritter" );
  225. putNum( out, "heizung", rs, "heizung" );
  226. // Pauschalen-Text nur, wenn *_P nicht NULL und Lookup Treffer:
  227. out.put( "heizungP",
  228. resolvePauschaleOrNull( dbCall, rs.getString( "heizungP_raw" ), "HEIZKOSTENPAUSCHALE", recht ) );
  229. putNum( out, "warmwasser", rs, "warmwasser" );
  230. out.put( "warmwasserP",
  231. resolvePauschaleOrNull( dbCall, rs.getString( "warmwasserP_raw" ), "WARMWASSERPAUSCHALE",
  232. recht ) );
  233. putNum( out, "moeblierung", rs, "moeblierung" );
  234. out.put( "moeblierungP",
  235. resolvePauschaleOrNull( dbCall, rs.getString( "moeblierungP_raw" ), "MOEBLIERUNGSPAUSCHALE",
  236. recht ) );
  237. putNum( out, "umietZuschlag", rs, "umietZuschlag" );
  238. putNum( out, "gewerbeZuschlag", rs, "gewerbeZuschlag" );
  239. out.put( "gewerbeZuschlagP",
  240. resolvePauschaleOrNull( dbCall, rs.getString( "gewerbeZuschlagP_raw" ), "GEWERBEPAUSCHALE",
  241. recht ) );
  242. putNum( out, "gewerbeFlaeche", rs, "gewerbeFlaeche" );
  243. putNum( out, "jhrlFernwarmw", rs, "jhrlFernwarmw" );
  244. putNum( out, "jhrlFernwaerme", rs, "jhrlFernwaerme" );
  245. putNum( out, "antMietWw", rs, "antMietWw" );
  246. putNum( out, "antBrutWw", rs, "antBrutWw" );
  247. putNum( out, "jhrlFernWUndW", rs, "jhrlFernWUndW" );
  248. putNum( out, "lstgAufenthaltPerson", rs, "lstgAufenthaltPerson" );
  249. putNum( out, "sonstWogFaehigBetrag", rs, "sonstWogFaehigBetrag" );
  250. // Ensure string fields are never null
  251. String sonstWogFaehigText = rs.getString( "sonstWogFaehigText" );
  252. out.put( "sonstWogFaehigText", sonstWogFaehigText != null ? sonstWogFaehigText : "" );
  253. String sonstZuschlagBeschr = rs.getString( "sonstZuschlagBeschr" );
  254. out.put( "sonstZuschlagBeschr", sonstZuschlagBeschr != null ? sonstZuschlagBeschr : "" );
  255. putNum( out, "energie", rs, "energie" );
  256. out.put( "energieP",
  257. resolvePauschaleOrNull( dbCall, rs.getString( "energieP_raw" ), "ENERGIEPAUSCHALE", recht ) );
  258. putNum( out, "stellplatz", rs, "stellplatz" );
  259. out.put( "stellplatzP",
  260. resolvePauschaleOrNull( dbCall, rs.getString( "stellplatzP_raw" ), "STELLPLATZPAUSCHALE",
  261. recht ) );
  262. }
  263. return out;
  264. }
  265. private static String resolvePauschaleOrNull ( IInwoDBCall dbCall, String rawValue, String art,
  266. String recht ) throws SQLException {
  267. if ( rawValue == null )
  268. return null;
  269. if ( recht == null || recht.isEmpty() )
  270. return null;
  271. return lookupPauschaleBeschreibung( dbCall, rawValue, art, recht ); // null, wenn kein Treffer
  272. }
  273. private static String lookupPauschaleBeschreibung ( IInwoDBCall dbCall, String kuerzel, String art,
  274. String recht ) throws SQLException {
  275. String q = "SELECT BESCHREIBUNG FROM T_PAUSCHALE WHERE KUERZEL = :kuerzel AND ART = :art AND RECHT = :recht";
  276. dbCall.query( q );
  277. dbCall.in( "kuerzel", kuerzel, Types.VARCHAR );
  278. dbCall.in( "art", art, Types.VARCHAR );
  279. dbCall.in( "recht", recht, Types.VARCHAR );
  280. ResultSet rs = dbCall.executeQuery( true );
  281. if ( rs.next() )
  282. return rs.getString( "BESCHREIBUNG" );
  283. return null;
  284. }
  285. /* ===================== Untermieter / Mitbewohner ===================== */
  286. private static List<Map<String, Object>> fetchUntermieter ( IInwoDBCall dbCall, Integer mieteIdOrNull,
  287. String recht ) throws SQLException {
  288. String q =
  289. "SELECT TO_CHAR(u.MI_ID) AS miId, u.LFDNR, u.NAME, u.VORNAME, u.FLAECHE, u.MIETE, u.HEIZUNG, " +
  290. " u.HEIZUNG_P AS heizungP_raw, u.WARMWASSER, u.WARMWASSER_P AS warmwasserP_raw, " +
  291. " u.MOEBLIERUNG, u.MOEBLIERUNG_P AS moeblierungP_raw, u.SONST " +
  292. "FROM T_UNTERMIETEN u WHERE u.MI_ID = COALESCE(:miete_id, 1) ORDER BY u.LFDNR";
  293. dbCall.query( q );
  294. dbCall.in( "miete_id", mieteIdOrNull, Types.INTEGER );
  295. List<Map<String, Object>> out = new ArrayList<>();
  296. ResultSet rs = dbCall.executeQuery( true );
  297. while ( rs.next() ) {
  298. Map<String, Object> row = new LinkedHashMap<>();
  299. row.put( "miId", rs.getString( "miId" ) );
  300. row.put( "lfdnr", ( ( BigDecimal ) rs.getObject( "LFDNR" ) ).intValue() );
  301. String name = rs.getString( "NAME" );
  302. row.put( "name", name != null ? name : "" );
  303. String vorname = rs.getString( "VORNAME" );
  304. row.put( "vorname", vorname != null ? vorname : "" );
  305. putNum( row, "flaeche", rs, "FLAECHE" );
  306. putNum( row, "miete", rs, "MIETE" );
  307. putNum( row, "heizung", rs, "HEIZUNG" );
  308. // Pauschalen-Text nur, wenn *_P nicht NULL und Lookup Treffer:
  309. row.put( "heizungP",
  310. resolvePauschaleOrNull( dbCall, rs.getString( "heizungP_raw" ), "HEIZKOSTENPAUSCHALE", recht ) );
  311. putNum( row, "warmwasser", rs, "WARMWASSER" );
  312. row.put( "warmwasserP",
  313. resolvePauschaleOrNull( dbCall, rs.getString( "warmwasserP_raw" ), "WARMWASSERPAUSCHALE",
  314. recht ) );
  315. putNum( row, "moeblierung", rs, "MOEBLIERUNG" );
  316. row.put( "moeblierungP",
  317. resolvePauschaleOrNull( dbCall, rs.getString( "moeblierungP_raw" ), "MOEBLIERUNGSPAUSCHALE",
  318. recht ) );
  319. putNum( row, "sonst", rs, "SONST" );
  320. out.add( row );
  321. }
  322. return out;
  323. }
  324. private static List<Map<String, Object>> fetchMitbewohner ( IInwoDBCall dbCall,
  325. Integer mieteIdOrNull, String recht ) throws SQLException {
  326. String q =
  327. "SELECT TO_CHAR(mb.MI_ID) AS miId, mb.LFDNR, mb.NAME, mb.VORNAME, mb.ENTGELT, mb.HEIZUNG, " +
  328. " mb.HEIZUNG_P AS heizungP_raw, mb.WARMWASSER, mb.WARMWASSER_P AS warmwasserP_raw, mb.SONST " +
  329. "FROM T_MITBEWOHNER mb WHERE mb.MI_ID = COALESCE(:miete_id, 1) ORDER BY mb.LFDNR";
  330. dbCall.query( q );
  331. dbCall.in( "miete_id", mieteIdOrNull, Types.INTEGER );
  332. List<Map<String, Object>> out = new ArrayList<>();
  333. ResultSet rs = dbCall.executeQuery( true );
  334. while ( rs.next() ) {
  335. Map<String, Object> row = new LinkedHashMap<>();
  336. row.put( "miId", rs.getString( "miId" ) );
  337. row.put( "lfdnr", ( ( BigDecimal ) rs.getObject( "LFDNR" ) ).intValue() );
  338. String name = rs.getString( "NAME" );
  339. row.put( "name", name != null ? name : "" );
  340. String vorname = rs.getString( "VORNAME" );
  341. row.put( "vorname", vorname != null ? vorname : "" );
  342. putNum( row, "entgelt", rs, "ENTGELT" );
  343. putNum( row, "heizung", rs, "HEIZUNG" );
  344. // Pauschalen-Text nur, wenn *_P nicht NULL und Lookup Treffer:
  345. row.put( "heizungP",
  346. resolvePauschaleOrNull( dbCall, rs.getString( "heizungP_raw" ), "HEIZKOSTENPAUSCHALE", recht ) );
  347. putNum( row, "warmwasser", rs, "WARMWASSER" );
  348. row.put( "warmwasserP",
  349. resolvePauschaleOrNull( dbCall, rs.getString( "warmwasserP_raw" ), "WARMWASSERPAUSCHALE", recht ) );
  350. putNum( row, "sonst", rs, "SONST" );
  351. out.add( row );
  352. }
  353. return out;
  354. }
  355. /* ===================== Ausstattung (mit S-Tabellen) ===================== */
  356. private static Map<String, Object> fetchAusstattung ( IInwoDBCall dbCall, Integer ausstattungId,
  357. Date eingangsdatum ) throws SQLException {
  358. java.sql.Date ed =
  359. ( eingangsdatum != null ) ? new java.sql.Date( eingangsdatum.getTime() ) :
  360. java.sql
  361. .Date
  362. .valueOf( "2099-12-31" );
  363. String q =
  364. "SELECT " + " TO_CHAR(a.ID) AS id, " + " a.FLAECHE AS flaeche, " +
  365. " COALESCE(heiz.BESCHREIBUNG, a.HEIZUNG) AS heizung, " +
  366. " COALESCE(badart.BESCHREIBUNG, a.BAD) AS bad, " + " a.SOZBAU_JN AS sozBauJn_raw, " +
  367. " COALESCE(mietv.BESCHREIBUNG, a.MIETVERHAELTNIS) AS mietverhaeltnis, " +
  368. " COALESCE(eigent.BESCHREIBUNG, a.EIGENTUM) AS eigentum, " +
  369. " TO_CHAR(a.FERTIG_DAT, 'YYYY-MM-DD') AS fertigDat, " +
  370. " a.NAME_EIG AS nameEig, a.ADRESSE_EIG AS adresseEig, a.TELEFON_EIG AS telefonEig, " +
  371. " a.WOFG_JN AS wofgJn_raw, a.FOERDERUNG_JN AS foerderungJn_raw " + "FROM T_AUSSTATTUNGEN a " +
  372. "LEFT JOIN T_SHEIZUNGSARTEN heiz " + " ON heiz.WERT = a.HEIZUNG " +
  373. " AND :eingang_dat >= heiz.AB_DAT " +
  374. " AND :eingang_dat <= NVL(heiz.BIS_DAT, DATE '9999-12-31') " + "LEFT JOIN T_SBADARTEN badart " +
  375. " ON badart.WERT = a.BAD " + " AND :eingang_dat >= badart.AB_DAT " +
  376. " AND :eingang_dat <= NVL(badart.BIS_DAT, DATE '9999-12-31') " +
  377. "LEFT JOIN T_SMIETVERHAELTNISSE mietv " + " ON mietv.WERT = a.MIETVERHAELTNIS " +
  378. " AND :eingang_dat >= mietv.AB_DAT " +
  379. " AND :eingang_dat <= NVL(mietv.BIS_DAT, DATE '9999-12-31') " + "LEFT JOIN T_SEIGENTUMSARTEN eigent " +
  380. " ON eigent.WERT = a.EIGENTUM " + " AND :eingang_dat >= eigent.AB_DAT " +
  381. " AND :eingang_dat <= NVL(eigent.BIS_DAT, DATE '9999-12-31') " + "WHERE a.ID = :ausstattung_id";
  382. dbCall.query( q );
  383. dbCall.in( "eingang_dat", ed, Types.DATE );
  384. dbCall.in( "eingang_dat", ed, Types.DATE );
  385. dbCall.in( "eingang_dat", ed, Types.DATE );
  386. dbCall.in( "eingang_dat", ed, Types.DATE );
  387. dbCall.in( "eingang_dat", ed, Types.DATE );
  388. dbCall.in( "eingang_dat", ed, Types.DATE );
  389. dbCall.in( "eingang_dat", ed, Types.DATE );
  390. dbCall.in( "eingang_dat", ed, Types.DATE );
  391. dbCall.in( "ausstattung_id", ausstattungId, Types.INTEGER );
  392. Map<String, Object> out = new LinkedHashMap<>();
  393. ResultSet rs = dbCall.executeQuery( true );
  394. if ( rs.next() ) {
  395. out.put( "id", "1" ); // Always set ausstattung ID to "1" in JSON output
  396. putNum( out, "flaeche", rs, "flaeche" );
  397. String heizung = rs.getString( "heizung" );
  398. out.put( "heizung", heizung != null ? heizung : "" );
  399. String bad = rs.getString( "bad" );
  400. out.put( "bad", bad != null ? bad : "" );
  401. out.put( "sozBauJn", "J".equalsIgnoreCase( rs.getString( "sozBauJn_raw" ) ) );
  402. String mietverhaeltnis = rs.getString( "mietverhaeltnis" );
  403. out.put( "mietverhaeltnis", mietverhaeltnis != null ? mietverhaeltnis : "" );
  404. String eigentum = rs.getString( "eigentum" );
  405. out.put( "eigentum", eigentum != null ? eigentum : "" );
  406. String fertig = rs.getString( "fertigDat" );
  407. if ( fertig != null )
  408. out.put( "fertigDat", fertig );
  409. String nameEig = rs.getString( "nameEig" );
  410. out.put( "nameEig", nameEig != null ? nameEig : "" );
  411. String adresseEig = rs.getString( "adresseEig" );
  412. out.put( "adresseEig", adresseEig != null ? adresseEig : "" );
  413. String telefonEig = rs.getString( "telefonEig" );
  414. out.put( "telefonEig", telefonEig != null ? telefonEig : "" );
  415. out.put( "wofgJn", "J".equalsIgnoreCase( rs.getString( "wofgJn_raw" ) ) );
  416. out.put( "foerderungJn", "J".equalsIgnoreCase( rs.getString( "foerderungJn_raw" ) ) );
  417. }
  418. return out;
  419. }
  420. }