You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ReservationApplication.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.itmill.toolkit.demo.reservation;
  5. import java.awt.geom.Point2D;
  6. import java.util.Calendar;
  7. import java.util.Date;
  8. import java.util.Iterator;
  9. import java.util.LinkedList;
  10. import java.util.List;
  11. import com.itmill.toolkit.Application;
  12. import com.itmill.toolkit.data.Container;
  13. import com.itmill.toolkit.data.Item;
  14. import com.itmill.toolkit.data.Property.ValueChangeEvent;
  15. import com.itmill.toolkit.data.Property.ValueChangeListener;
  16. import com.itmill.toolkit.ui.Button;
  17. import com.itmill.toolkit.ui.Label;
  18. import com.itmill.toolkit.ui.OrderedLayout;
  19. import com.itmill.toolkit.ui.Panel;
  20. import com.itmill.toolkit.ui.TabSheet;
  21. import com.itmill.toolkit.ui.Table;
  22. import com.itmill.toolkit.ui.TextField;
  23. import com.itmill.toolkit.ui.Window;
  24. import com.itmill.toolkit.ui.TabSheet.SelectedTabChangeEvent;
  25. import com.itmill.toolkit.ui.Window.Notification;
  26. public class ReservationApplication extends Application {
  27. private SampleDB db;
  28. ResourceSelectorPanel resourcePanel;
  29. private CalendarField reservedFrom;
  30. private static final long DEFAULT_GAP_MILLIS = 3600000; // (almost) one
  31. // hour
  32. private long currentGapMillis = DEFAULT_GAP_MILLIS; // current length of
  33. // reservation
  34. private CalendarField reservedTo;
  35. private Label resourceName;
  36. private TextField description;
  37. private Button reservationButton;
  38. private Table allTable;
  39. private GoogleMap map;
  40. private Window popupWindow;
  41. private Label popupMessage;
  42. public void init() {
  43. db = new SampleDB(true);
  44. db.generateResources();
  45. db.generateDemoUser();
  46. db.generateReservations();
  47. final Window mainWindow = new Window("Reservr");
  48. setMainWindow(mainWindow);
  49. setTheme("reservr");
  50. final TabSheet mainTabs = new TabSheet();
  51. mainWindow.addComponent(mainTabs);
  52. final OrderedLayout reservationTab = new OrderedLayout();
  53. mainTabs.addTab(reservationTab, "Make reservation", null);
  54. resourcePanel = new ResourceSelectorPanel("Resources");
  55. resourcePanel.setResourceContainer(db.getResources(null));
  56. resourcePanel.addListener(
  57. ResourceSelectorPanel.SelectedResourcesChangedEvent.class,
  58. this, "selectedResourcesChanged");
  59. reservationTab.addComponent(resourcePanel);
  60. final Panel reservationPanel = new Panel("Reservation",
  61. new OrderedLayout(OrderedLayout.ORIENTATION_HORIZONTAL));
  62. reservationPanel.addStyleName(Panel.STYLE_LIGHT);
  63. reservationPanel.getLayout().setMargin(true);
  64. reservationTab.addComponent(reservationPanel);
  65. final OrderedLayout infoLayout = new OrderedLayout();
  66. infoLayout.setMargin(false, true, false, false);
  67. reservationPanel.addComponent(infoLayout);
  68. resourceName = new Label("From the list above");
  69. resourceName.setCaption("Choose resource");
  70. infoLayout.addComponent(resourceName);
  71. description = new TextField();
  72. description.setColumns(20);
  73. description.setRows(5);
  74. infoLayout.addComponent(description);
  75. reservationButton = new Button("Make reservation", this,
  76. "makeReservation");
  77. infoLayout.addComponent(reservationButton);
  78. map = new GoogleMap();
  79. // TODO support EM
  80. // map.setWidthUnits(Sizeable.UNITS_EM);
  81. map.setWidth(266);
  82. map.setHeight(210);
  83. map.setItemMarkerHtmlPropertyId(SampleDB.Resource.PROPERTY_ID_NAME);
  84. map.setItemMarkerXPropertyId(SampleDB.Resource.PROPERTY_ID_LOCATIONX);
  85. map.setItemMarkerYPropertyId(SampleDB.Resource.PROPERTY_ID_LOCATIONY);
  86. map.setContainerDataSource(db.getResources(null));
  87. infoLayout.addComponent(map);
  88. final Calendar from = Calendar.getInstance();
  89. from.add(Calendar.HOUR, 1);
  90. from.set(Calendar.MINUTE, 0);
  91. from.set(Calendar.SECOND, 0);
  92. from.set(Calendar.MILLISECOND, 0);
  93. reservedFrom = new CalendarField("From");
  94. reservedFrom.setMinimumDate(from.getTime());
  95. reservedFrom.setValue(from.getTime());
  96. reservedFrom.setImmediate(true);
  97. initCalendarFieldPropertyIds(reservedFrom);
  98. reservationPanel.addComponent(reservedFrom);
  99. final Label arrowLabel = new Label("»");
  100. arrowLabel.setContentMode(Label.CONTENT_XHTML);
  101. arrowLabel.setStyleName("arrow");
  102. reservationPanel.addComponent(arrowLabel);
  103. final Calendar to = Calendar.getInstance();
  104. to.setTime(from.getTime());
  105. to.add(Calendar.MILLISECOND, (int) DEFAULT_GAP_MILLIS);
  106. reservedTo = new CalendarField("To");
  107. reservedTo.setMinimumDate(to.getTime());
  108. reservedTo.setValue(to.getTime());
  109. reservedTo.setImmediate(true);
  110. initCalendarFieldPropertyIds(reservedTo);
  111. reservationPanel.addComponent(reservedTo);
  112. reservedFrom.addListener(new ValueChangeListener() {
  113. public void valueChange(ValueChangeEvent event) {
  114. final Date fd = (Date) reservedFrom.getValue();
  115. if (fd == null) {
  116. reservedTo.setValue(null);
  117. reservedTo.setEnabled(false);
  118. refreshSelectedResources();
  119. return;
  120. } else {
  121. reservedTo.setEnabled(true);
  122. }
  123. reservedTo.setMinimumDate(new Date(fd.getTime()
  124. + DEFAULT_GAP_MILLIS));
  125. final Calendar to = Calendar.getInstance();
  126. to.setTime(fd);
  127. to.add(Calendar.MILLISECOND, (int) currentGapMillis);
  128. reservedTo.setValue(to.getTime());
  129. refreshSelectedResources();
  130. }
  131. });
  132. reservedTo.addListener(new ValueChangeListener() {
  133. public void valueChange(ValueChangeEvent event) {
  134. final Date from = (Date) reservedFrom.getValue();
  135. final Date to = (Date) reservedTo.getValue();
  136. currentGapMillis = to.getTime() - from.getTime();
  137. if (currentGapMillis <= 0) {
  138. final Calendar t = Calendar.getInstance();
  139. t.setTime(from);
  140. t.add(Calendar.MILLISECOND, (int) DEFAULT_GAP_MILLIS);
  141. reservedTo.setValue(t.getTime());
  142. }
  143. refreshSelectedResources();
  144. }
  145. });
  146. final OrderedLayout allLayout = new OrderedLayout(
  147. OrderedLayout.ORIENTATION_HORIZONTAL);
  148. allLayout.addStyleName(Panel.STYLE_LIGHT);
  149. allLayout.setMargin(true);
  150. allTable = new Table();
  151. allTable.setHeight(300);
  152. allTable.setWidth(700);
  153. allTable.setColumnCollapsingAllowed(true);
  154. allTable.setColumnReorderingAllowed(true);
  155. allLayout.addComponent(allTable);
  156. mainTabs.addTab(allLayout, "All reservations", null);
  157. mainTabs.addListener(new TabSheet.SelectedTabChangeListener() {
  158. public void selectedTabChange(SelectedTabChangeEvent event) {
  159. refreshReservations(false);
  160. }
  161. });
  162. resourcePanel.selectFirstCategory();
  163. refreshReservations(true);
  164. }
  165. public void makeReservation() {
  166. try {
  167. final Item resource = getActiveResource();
  168. if (resource != null) {
  169. db.addReservation(resource, 0, (Date) reservedFrom.getValue(),
  170. (Date) reservedTo.getValue(), (String) description
  171. .getValue());
  172. getMainWindow()
  173. .showNotification(
  174. "Success!",
  175. "You have reserved the resource for the selected period.",
  176. Notification.TYPE_WARNING_MESSAGE);
  177. refreshReservations(false);
  178. } else {
  179. getMainWindow().showNotification("Oops!",
  180. "Please select a resource (or category) to reserve.",
  181. Notification.TYPE_WARNING_MESSAGE);
  182. }
  183. } catch (final ResourceNotAvailableException e) {
  184. getMainWindow()
  185. .showNotification(
  186. "Not available!",
  187. "The selected resource is already reserved for the selected period.",
  188. Notification.TYPE_ERROR_MESSAGE);
  189. refreshReservations(false);
  190. }
  191. }
  192. private Item getActiveResource() throws ResourceNotAvailableException {
  193. final List rids = resourcePanel.getSelectedResources();
  194. if (rids != null && rids.size() > 0) {
  195. for (final Iterator it = rids.iterator(); it.hasNext();) {
  196. final Item resource = (Item) it.next();
  197. final int id = ((Integer) resource.getItemProperty(
  198. SampleDB.Resource.PROPERTY_ID_ID).getValue())
  199. .intValue();
  200. if (db.isAvailableResource(id, (Date) reservedFrom.getValue(),
  201. (Date) reservedTo.getValue())) {
  202. return resource;
  203. }
  204. }
  205. throw new ResourceNotAvailableException("No available resources");
  206. } else {
  207. return null;
  208. }
  209. }
  210. private void refreshReservations(boolean alsoResources) {
  211. final Container reservations = db.getReservations(resourcePanel
  212. .getSelectedResources());
  213. reservedFrom.setContainerDataSource(reservations);
  214. reservedTo.setContainerDataSource(reservations);
  215. if (alsoResources) {
  216. refreshSelectedResources();
  217. }
  218. final Container allReservations = db.getReservations(null);
  219. allTable.setContainerDataSource(allReservations);
  220. if (allReservations != null && allReservations.size() > 0) {
  221. allTable.setVisibleColumns(new Object[] {
  222. SampleDB.Reservation.PROPERTY_ID_RESERVED_FROM,
  223. SampleDB.Reservation.PROPERTY_ID_RESERVED_TO,
  224. SampleDB.Resource.PROPERTY_ID_NAME,
  225. SampleDB.Resource.PROPERTY_ID_DESCRIPTION,
  226. SampleDB.Reservation.PROPERTY_ID_DESCRIPTION });
  227. allTable.setColumnHeaders(new String[] { "From", "To", "Resource",
  228. "Description", "Message" });
  229. }
  230. }
  231. private void refreshSelectedResources() {
  232. Item resource = null;
  233. try {
  234. resource = getActiveResource();
  235. } catch (final ResourceNotAvailableException e) {
  236. getMainWindow().showNotification("Not available",
  237. "Please choose another resource or time period.",
  238. Notification.TYPE_HUMANIZED_MESSAGE);
  239. return;
  240. }
  241. map.clear();
  242. if (resource == null) {
  243. resourceName.setCaption("Choose resource above");
  244. resourceName.setValue("");
  245. map.setContainerDataSource(db.getResources(null));
  246. map.setZoomLevel(1);
  247. } else {
  248. // Display active resource name + desc
  249. String name = (String) resource.getItemProperty(
  250. SampleDB.Resource.PROPERTY_ID_NAME).getValue();
  251. String desc = (String) resource.getItemProperty(
  252. SampleDB.Resource.PROPERTY_ID_DESCRIPTION).getValue();
  253. resourceName.setCaption(name);
  254. resourceName.setValue(desc);
  255. // Put all resources on map (may be many if category was selected)
  256. final LinkedList srs = resourcePanel.getSelectedResources();
  257. for (final Iterator it = srs.iterator(); it.hasNext();) {
  258. resource = (Item) it.next();
  259. name = (String) resource.getItemProperty(
  260. SampleDB.Resource.PROPERTY_ID_NAME).getValue();
  261. desc = (String) resource.getItemProperty(
  262. SampleDB.Resource.PROPERTY_ID_DESCRIPTION).getValue();
  263. final Double x = (Double) resource.getItemProperty(
  264. SampleDB.Resource.PROPERTY_ID_LOCATIONX).getValue();
  265. final Double y = (Double) resource.getItemProperty(
  266. SampleDB.Resource.PROPERTY_ID_LOCATIONY).getValue();
  267. if (x != null && y != null) {
  268. map.addMarker(name + "<br/>" + desc, new Point2D.Double(x
  269. .doubleValue(), y.doubleValue()));
  270. }
  271. }
  272. map.setZoomLevel((srs.size() == 1 ? 14 : 9));
  273. }
  274. }
  275. private void initCalendarFieldPropertyIds(CalendarField cal) {
  276. cal.setItemStyleNamePropertyId(SampleDB.Resource.PROPERTY_ID_STYLENAME);
  277. cal
  278. .setItemStartPropertyId(SampleDB.Reservation.PROPERTY_ID_RESERVED_FROM);
  279. cal.setItemEndPropertyId(SampleDB.Reservation.PROPERTY_ID_RESERVED_TO);
  280. cal.setItemTitlePropertyId(SampleDB.Resource.PROPERTY_ID_NAME);
  281. cal
  282. .setItemDescriptionPropertyId(SampleDB.Reservation.PROPERTY_ID_DESCRIPTION);
  283. }
  284. public void selectedResourcesChanged(
  285. ResourceSelectorPanel.SelectedResourcesChangedEvent event) {
  286. refreshReservations(true);
  287. }
  288. }