001 /***************************************************************************** 002 * MODULE DESCRIPTION 003 ****************************************************************************** 004 * 005 * NAME: KiuruReservation.java 006 * LANGUAGE: Java 2 007 * DATE: 13.11.2002 008 * AUTHOR: Jussi Mäkinen, Jyväskylä University (JYU) 009 * PURPOSE: This module includes routines to check and make reservations 010 * that are not handled by any third party reservation systems. 011 * 012 ****************************************************************************** 013 * COPYRIGHT (C) Kiuru group 014 * Limited rights granted. Please refer to license 015 *****************************************************************************/ 016 package kiurubeans; 017 018 import kotkabeans.*; 019 import java.sql.*; 020 import java.util.ArrayList; 021 022 /** This class encapsulates actual making of reservations and getting information 023 * about already made reservations. 024 */ 025 public class KiuruReservation { 026 027 /** Reservation request */ 028 public final static int REQUEST_STATE_REQUEST = 1; 029 /** Reservation is being processed. Reserved for future use. */ 030 public final static int REQUEST_STATE_PROCESSING = 2; 031 /** Reservation is made and confirmed. This is the final state. */ 032 public final static int REQUEST_STATE_CONFIRMED = 3; 033 /** Reservation was made and then cancelled */ 034 public final static int REQUEST_STATE_CANCELLED = 4; 035 /** Somebody removed reservation. */ 036 public final static int REQUEST_STATE_REMOVED = 5; 037 038 /** Default constructor */ 039 public KiuruReservation() { 040 041 } 042 043 /** Assigns persons to a reservation 044 * @param cPerson personID of the contact person for the reservation 045 * @param resMaker personID of the person who actually made the reservation 046 * @param reservations Array of <CODE>Integers</CODE> containing <CODE>reservationID</CODE>s. 047 * @return <CODE>true</CODE> if no exceptions were thrown. 048 */ 049 public static boolean assignPersonsToReservation(int cPerson, int resMaker, 050 Integer[] reservations) { 051 boolean ok = false; 052 PreparedDB pdb = new PreparedDB(); 053 try { 054 pdb.connect("INSERT INTO reservationperson (deleted,personid,reservationid,reservationroleid) values ('false',?,?,?);",ResultSet.CONCUR_READ_ONLY); 055 for (int i=0;i<reservations.length;i++) { 056 if (reservations[i].intValue()>0) { 057 pdb.setInt(2,reservations[i].intValue()); 058 pdb.setInt(1,cPerson); 059 pdb.setInt(3,3); //Remember to delete magic numbers 060 pdb.executeUpdate(); 061 pdb.setInt(1,resMaker); 062 pdb.setInt(3,1); 063 pdb.executeUpdate(); 064 } 065 } 066 ok = true; 067 } 068 catch (Exception e) { ok = false; } 069 finally { 070 pdb.disconnect(); 071 } 072 return ok; 073 } 074 075 /** Checks if given space is reserved or free. 076 * @param spaceId Id of space 077 * @param eventId Time interval to be checked 078 * @return Returns false if given space is free during given event 079 * @throws java.lang.Exception If something went wrong in query 080 */ 081 public static boolean isReserved(int spaceId,int eventId) throws Exception{ 082 boolean reserved=false; 083 DB db = new DB("isReserved"); 084 try { 085 db.connect(); 086 ResultSet rs = db.executeQuery("SELECT e1.eventid from reservation,event as e1, "+ 087 "event as e2 where (e1.begintime,e1.endtime) overlaps "+ 088 "(e2.begintime,e2.endtime) and reservation.eventid=e1.eventid and "+ 089 "e2.eventid="+eventId+" and reservation.deleted=false and "+ 090 "reservation.spaceid="+spaceId+" and reservation.requeststateid=3 and "+ 091 "e1.deleted=false and e2.deleted=false;"); 092 if (rs.next()) {reserved=true;} 093 } 094 finally { 095 db.disconnect(); 096 } 097 return reserved; 098 } 099 100 /** Makes reservation to given space for given event 101 * @param spaceId Space that is going to be reserved. 102 * @param eventId Event that is going to be held. 103 * @param organisationId Organisation that is arranging the event. 104 * @param requestState If the reservation is final or proposition. 105 * @param reservationInfo Additional info 106 * @return id of made reservation or -1 if reservation was not successful 107 * @param user Who is making the reservation 108 * @throws Exception If something went wrong in database update 109 */ 110 public static int makeReservation(int spaceId, int eventId, int organisationId,int requestState,String reservationInfo, User user) throws Exception{ 111 int resId=-1; 112 if (eventId<1) return resId; 113 if (spaceId<1) return resId; 114 DB db = new DB("Add reservation"); 115 try { 116 if (!Event.checkUsersEventRights(eventId, user)) return resId; 117 if (isReserved(spaceId,eventId) && requestState > REQUEST_STATE_REQUEST) return resId; 118 if (requestState == REQUEST_STATE_REQUEST && !KiuruSpace.checkReservationRequestRight(spaceId,user)) 119 return resId; 120 if (requestState == REQUEST_STATE_CONFIRMED && !KiuruSpace.checkUserRights(spaceId,user)) 121 return resId; 122 db.connect(); 123 if (requestState==REQUEST_STATE_CONFIRMED) { 124 ResultSet rs = db.executeQuery("SELECT reservationid from reservation,event as e1, event as e2 where spaceid="+spaceId+" and reservation.eventid=e1.eventid and e2.eventid="+eventId+" and (e1.begintime,e1.endtime) overlaps (e2.begintime,e2.endtime) and reservation.requeststateid=3 and reservation.deleted='false' and e1.deleted='false' and e2.deleted='false';"); 125 if (rs.next()) { return -1;} 126 } 127 db.executeUpdate("UPDATE reservation SET deleted='true' where eventid="+eventId+" and deleted='false';"); 128 resId=AutoNumber.getNumber("Reservation"); 129 db.executeUpdate("INSERT INTO reservation (deleted,reservationid,spaceid,eventid,resorganisationid,payorganisationid,requeststateid,updatetime,description) values ('false',"+resId+","+spaceId+","+eventId+","+organisationId+","+organisationId+","+requestState+",NOW(),'"+kotkabeans.Encoder.SQLEncode(reservationInfo)+"');"); 130 db.executeUpdate("UPDATE eventspace set spaceid="+spaceId+" WHERE eventid="+eventId+" and deleted='false'"); 131 } 132 catch (Exception e) { 133 resId=-1; 134 } 135 finally { 136 db.disconnect(); 137 } 138 return resId; 139 } 140 141 142 /** Makes reservation to given space for given event 143 * @param spaceId Space that is going to be reserved. 144 * @param eventId Event that is going to be held. 145 * @param organisationId Organisation that is arranging the event. 146 * @param reservationInfo Additional info 147 * @return id of made reservation or -1 if reservation was not successful 148 * @param user Who is making the reservation 149 * @throws Exception If something went wrong in database update 150 */ 151 public static int makeReservation(int spaceId, int eventId, int organisationId,String reservationInfo,User user) throws Exception { 152 return makeReservation(spaceId,eventId,organisationId,1, reservationInfo,user); 153 } 154 155 /** Makes reservations to given space for given event 156 * @return id of made reservation or -1 if reservation was not successful 157 * @param spaceId Space that is going to be reserved. 158 * @param eventIds Events that are going to be held. 159 * @param organisationId Organisation that is arranging the event. 160 * @param reservationInfo Additional info 161 * @param user Who is making the reservation 162 * @param requestState If the reservation is final or proposition. 163 * @param payOrganisationId Organisation that is paying the event. 164 * @throws Exception If something went wrong in database update 165 */ 166 public static Integer[] makeReservation(int spaceId, Integer[] eventIds, int organisationId, int payOrganisationId, int requestState, String reservationInfo,User user) throws Exception{ 167 168 Integer[] resIds=new Integer[eventIds.length]; 169 for (int i=0;i<eventIds.length;i++) 170 resIds[i]=new Integer(makeReservation(spaceId,eventIds[i].intValue(),organisationId,requestState,reservationInfo,user)); 171 return resIds; 172 } 173 174 /** Adds person as a contact person into a reservation 175 * @param personID Id of the contact person 176 * @param reservationID Id of the reservation 177 * @throws Exception If something went wrong during database update 178 */ 179 public static void addPersonToReservation(int personID,int reservationID) throws Exception { 180 DB db = new DB("addPersonToReservation"); 181 try { 182 db.connect(); 183 db.executeUpdate("INSERT INTO reservationperson (deleted,personid,reservationid,reservationroleid) values ('false',"+personID+","+reservationID+",1);"); 184 } 185 finally { 186 db.disconnect(); 187 } 188 } 189 190 /** Returns state for current reservation, or empty string if there is 191 * no reservation. 192 * @param spaceId Id of space where reservation is made to 193 * @param eventId Id of the event that deals with reservation 194 * @return RequestState as a String. 195 */ 196 public static String getReservationState(int eventId, int spaceId) { 197 Log.log("START GETRESERVATIONSTATE"); 198 StringBuffer sb = new StringBuffer(20); 199 sb.append("SELECT rs.name as name FROM requeststate as rs, reservation as r "); 200 sb.append("WHERE r.eventid="+eventId+" and r.deleted=false "); 201 sb.append("AND r.requeststateid = rs.requeststateid "); 202 if (spaceId!=0) { 203 sb.append("AND r.spaceid ="+spaceId); 204 } 205 RS2 rs = null; 206 try { 207 Log.log("IN GETRESERVATIONSTATE"); 208 rs = SimpleDb.simpleQuery("Kiurureservation.getReservationState", sb.toString()); 209 if (!SimpleDb.isEmpty(rs)) { 210 Log.log("RS2 NONEMPTY"); 211 rs.next(); 212 return rs.getString("name"); 213 } 214 else { 215 return "Ei varausta"; 216 } 217 } 218 catch (Exception e) { 219 return "VIRHE!"; 220 } 221 } 222 223 /** Determines if given event is reserved (+confirmed) at given space. We use 224 * this method in order to avoid double reservations. 225 * @return true if reservation is confirmed 226 * @param eventId Id of event that is checked 227 * @param spaceId Id of space where event should occur. 228 */ 229 public static boolean isReservationOk(int eventId,int spaceId) { 230 boolean isOk=false; 231 DB db = new DB("isReservationOk"); 232 try { // 3 == confirmed 233 String query="SELECT reservationid from reservation where eventid="+eventId+" and deleted='false' and requeststateid=3"; 234 if (spaceId!=0) {query=query+" and spaceid="+spaceId;} 235 db.connect(); 236 237 ResultSet rs = db.executeQuery(query); 238 if (rs.next()) {isOk=true;} 239 } 240 catch (Exception e) { 241 isOk=false; 242 } 243 finally { 244 db.disconnect(); 245 } 246 return isOk; 247 } 248 249 /** Determines if there is reservation for given event. 250 * @param eventId Id of given event 251 * @return true if reservation is made and confirmed 252 */ 253 public static boolean isReservationOk(int eventId) { 254 return isReservationOk(eventId,0); 255 } 256 257 /** Returns contact person of given reservation 258 * @param reservationId Id of reservation as String 259 * @throws Exception If something went wrong in database query 260 * @return PersonID of the contact person 261 */ 262 public static int getReservationPerson(String reservationId) throws Exception { 263 int personId=-1; 264 try { 265 personId=getReservationPerson(Integer.parseInt(reservationId)); 266 } 267 catch (NumberFormatException nfe) {personId=-1;} 268 return personId; 269 } 270 271 /** Returns contact person of given reservation 272 * @return PersonID of contact person. 273 * @param reservationId ReservationId 274 * @throws Exception If something went wrong in database query 275 */ 276 277 public static int getReservationPerson(int reservationId) throws Exception{ 278 DB db = new DB("getReservationPerson"); 279 int person=-1; 280 try { 281 String query="select personid from reservationperson as rp "+ 282 "where rp.reservationid="+reservationId+ 283 " and rp.reservationroleid=3 "+ 284 "and rp.deleted='f' "+ 285 "limit 1 "; 286 db.connect(); 287 ResultSet rs = db.executeQuery(query); 288 if (rs.next()) { 289 person=rs.getInt("personid"); 290 } 291 } 292 finally { 293 db.disconnect(); 294 } 295 return person; 296 } 297 298 /** Returns eventid of given reservation 299 * @param reservationId Id of the given reservation 300 * @return eventID 301 */ 302 public static int getEventId(String reservationId) { 303 int eventId=-1; 304 try { 305 eventId=getEventId(Integer.parseInt(reservationId)); 306 } 307 catch (NumberFormatException nfe) {eventId=-1;} 308 return eventId; 309 } 310 311 /** Returns eventid of given reservation 312 * @return eventId 313 * @param reservationId Id of the given reservation 314 */ 315 316 public static int getEventId(int reservationId) { 317 DB db = new DB("getEventId"); 318 int event=-1; 319 try { 320 String query="select eventid from reservation as r "+ 321 "where r.reservationid="+reservationId+ 322 " and r.deleted='f'"; 323 db.connect(); 324 ResultSet rs = db.executeQuery(query); 325 if (rs.next()) { 326 event=rs.getInt("eventid"); 327 } 328 } 329 catch (Exception e) { 330 event=-1; 331 } 332 finally { 333 db.disconnect(); 334 } 335 return event; 336 } 337 338 /** Returns EventID and EventGroupID of given reservation in int array. 339 * @return int array where array[0]=eventId and array[1]=eventGroupId 340 * @param reservationId Id of reservation as String 341 * @throws Exception If something went wrong in database query 342 */ 343 public static int[] getEventAndEventGroupId(String reservationId) throws Exception { 344 int results[]; 345 try { 346 results=getEventAndEventGroupId(Integer.parseInt(reservationId)); 347 } 348 catch (NumberFormatException nfe) {results=null;} 349 return results; 350 } 351 352 /** Returns EventID and EventGroupID of given reservation in int array. 353 * @param reservationId Id of reservation 354 * @throws Exception If something went wrong in database query 355 * @return int array where array[0]=eventId and array[1]=eventGroupId 356 */ 357 public static int[] getEventAndEventGroupId(int reservationId) throws Exception { 358 DB db = new DB("getEventId"); 359 int event=-1; 360 int eventGroup=-1; 361 try { 362 String query="select event.eventid, eventgroupid from reservation as r,event "+ 363 "where r.eventid=event.eventid and r.reservationid="+reservationId+ 364 " and r.deleted='f' and event.eventid=reservation.eventid and "+ 365 "event.deleted='f'"; 366 db.connect(); 367 ResultSet rs = db.executeQuery(query); 368 if (rs.next()) { 369 event=rs.getInt("eventid"); 370 eventGroup=rs.getInt("eventgroupid"); 371 } 372 } 373 finally { 374 db.disconnect(); 375 } 376 int[] results = new int[2]; 377 results[0]=event; 378 results[1]=eventGroup; 379 return results; 380 } 381 /* public static int getReservationOverlappingCount(int reservationid) { 382 383 select count(*) from reservation where 384 reservationid in 385 (SELECT distinct r.reservationid FROM event AS e1, event AS e2,eventspace AS es1, eventspace AS es2, reservation as r WHERE (e1.begintime,e1.endtime) OVERLAPS (e2.begintime,e2.endtime) AND e1.begintime>NOW() AND es2.eventid=e2.eventid AND es1.eventid=e1.eventid AND es2.spaceid=es1.spaceid AND e1.eventid<>e2.eventid AND es1.spaceid<>0 AND e1.deleted='false' AND e2.deleted='false' AND es1.deleted='false' AND es2.deleted='false' and es1.spaceid=r.spaceid and e1.eventid=r.eventid 386 and r.requeststateid<4 387 and r.spaceid in ( 388 select spaceid from reservation 389 where reservationid=493 390 ) 391 and r.reservationid<>493 392 ) 393 }*/ 394 395 /** Checks if given user has access to modify reservation (or anything administrial) 396 * @param reservationId Id of reservation to be checked 397 * @param user User who tries to modify reservation 398 * @return true if user is allowed to modify reservation 399 */ 400 public static boolean checkUsersReservationRights(int reservationId, User user) { 401 int eventId = getEventId(reservationId); 402 if (kotkabeans.Event.checkUsersEventRights(eventId, user)) return true; 403 DB db = new DB("checkUsersReservationRights"); 404 try { 405 db.connect(); 406 ResultSet rs = db.executeQuery("SELECT reservationroleid from"+ 407 " reservationperson where deleted='f' and personid="+user.getPersonID()+ 408 " and reservationid="+reservationId); 409 if (rs.next()) { 410 return true; 411 } 412 } 413 catch (Exception e) { 414 return false; 415 } 416 finally { 417 db.disconnect(); 418 } 419 420 return false; 421 } 422 423 /** Changes states of specified reservation requests into reservations 424 * @return Returns reservation requests that couldn't be accepted. The main reason for this 425 * is the space is not free. 426 * @param reservations Array of Strings containing <CODE>reservationID</CODE>s we are accepting. 427 */ 428 public static ArrayList acceptReservationRequests(String[] reservations) { 429 ArrayList failure = new ArrayList(10); 430 if (reservations==null || reservations.length<1) return failure; 431 DB db = new DB(); 432 int i=0; 433 try { 434 db.connect(); 435 for (i=0;i<reservations.length;i++) { 436 ResultSet rs = db.executeQuery("SELECT e2.eventid as eventid FROM eventgroup AS eg1, event AS e1, " 437 +"event AS e2,reservation AS es1, reservation AS es2 WHERE (e1.begintime,e1.endtime) " 438 +"OVERLAPS (e2.begintime,e2.endtime) AND e1.begintime>NOW() AND es2.eventid=e2.eventid " 439 +"AND es1.eventid=e1.eventid AND es2.spaceid=es1.spaceid AND e1.eventid<>e2.eventid AND " 440 +"es1.spaceid<>0 AND e1.deleted='false' AND e2.deleted='false' AND es1.deleted='false' " 441 +"AND es2.deleted='false' AND e1.eventgroupid=eg1.eventgroupid AND es1.reservationid="+reservations[i]+" " 442 +"AND es2.requeststateid="+REQUEST_STATE_CONFIRMED+" ORDER BY e1.begintime;"); 443 if (rs.next()) {failure.add(reservations[i]);} 444 if (!failure.contains(reservations[i])) { 445 int ok = db.executeUpdate("UPDATE reservation SET requeststateid="+REQUEST_STATE_CONFIRMED+" where requeststateid = "+REQUEST_STATE_REQUEST+" and reservationid="+reservations[i]+";"); 446 if (ok!=1) {failure.add(reservations[i]);} 447 } 448 } 449 } 450 catch (Exception e) { 451 for (int j=i;j<reservations.length;j++) { 452 if (!failure.contains(reservations[j])) 453 failure.add(reservations[j]); 454 } 455 } 456 finally { 457 db.disconnect(); 458 } 459 return failure; 460 } 461 }