Blog do projektu Open Source JavaHotel

Pokazywanie postów oznaczonych etykietą javahotel. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą javahotel. Pokaż wszystkie posty

poniedziałek, 31 października 2016

New features in Jython MVP framework, more Polymer

Introduction
I implemented next bunch of Polymer web components from GWT Polymer show case. New components implemented: Header Panel, Icon Button, Item, Input, Material, Menu, Progress, Radio Button, Radio Group, Ripple, Spinner, Tabs.
The demo is launched from here, the source code is here.
Example screenshots


ui:style
I also implemented ui:style element with CSS class name obfuscation. This way we can have a "private" CSS class name without the risk, that "local" class name will collide with other CSS class definitions. Also, the framework does not allow to use misspelled class names.
An example for UIBinder with ui:style element.
Pending problems
  • Popup dialogs do not work in Firefox browser
  • Not all web components render well, for instance: Tabs
  • Implementation of Progress component is still waiting for action for "Start" button
Next steps
Continue with Paper components. Having ui:style element implemented, makes copying and pasting UIBinder files from GWT Polymer show case easier.



sobota, 30 lipca 2016

New features in Jython MVP framework

Introduction
I started playing around with Vaadin Gwt Polymer and decided to implement this feature in my Jython MVP framework. The source code is available here, show demo version can be launched through this address (it could take several minutes until Google App Engine instance is activated). Important : does not work properly in Firefox, tested with Chrome only.
New features are consumed in two ways:
Polymer implementation


XML definition
In order to activate Polymer rendering "polymer" attribute should be added. Widgets implemented so far: menu, combo (PaperDropdownMenu), main panel, editing. A list is not implemented yet. A date picker is implemented by standard GWT DatePicker widget, I was unable to find Polymer equivalent.
Dynamic UI Binder
Polymer rendering described above comes with one obstacle. In order to give access to all Polymer properties, it would be necessary to extend the xml definition by a huge number of additional attributes mapping to appropriate Polymer properties. It is resolved by GWT UiBinder which is not applicable for Jython MVP framework because UI Binder is resolved statically, during compilation. So I decided to develop my own UI Binder implementation, resolved dynamically. In a sample application, I implemented several Paper Elements from Vaadim GWT Polymer show case.
GWT UI Binder format is not mutually intelligible with MVP Jython UI Binder format. But both share the logic, I found quite easy to adapt UI Binder from Vaadim show case for a  sample application. An example of UIBinder for above dialog is available here, fieldid attribute binds UIBnder element with corresponding field or button element, like GWT UIBinder ui:field attribute.
Java code for dynamic UI Binder is here. Of course, it is not possible to use reflection in GWT context, so the only solution is a painstaking manual setting of all corresponding attributes.
Next steps
Implementing all samples from GWT Vaadin Polymer show case.


czwartek, 31 grudnia 2015

New version of JavaHotel application

Introduction
The new version of JavaHotel application has been deployed. Demo version (U/P user/user), full source code is available here. A new option is a journal, a register of daily activities of the user. The journal gives the manager an insight into daily business and workload of all users.
Journal
Journal is available from upper menu: Administrator->Journal

A subset of user action is recorded, the actions related to changes in the status of database and reservation or some customer actions like sending a confirmation note or registering a payment.
Filtering
Also, a convenient journal filtering is implemented. Activities can be filtered on users and activity type.


Future

  • Graphic presentation of journal
  • More granular reporting related to the time of the day, answering the question: "at what time of the day some type of action is more frequent ?"

czwartek, 8 października 2015

New features in Jython MVP framework

Introduction
I added several improvements to Jython MVP framework. The source code is available here. Demo version running in  Google App Engine is here.
Change focus
This feature allows an automatic jump to the particular field in the form. Is useful at the beginning allowing user start entering data in the proper field or, in case of error detected, move to the wrong field. This option is demonstrated in the demo application, Alerts -> Dialog with focus.

More detailed description.
Field with dynamic list of images
This option was created firstly for the editable list. But now it is extended to form as well. Declaration and handling are very similar. More details. The option is showed in the demo application, Alerts -> Dialog with image field.

sobota, 11 lipca 2015

New version of MVP Jython framework

Introduction
New version has been deployed. Introduces new functionality and enhancements.
Source code and and Google App Engine demo version.
Hide and show columns in list programmatically
Columns can be hidden and revealed again from Jython code. More detailed description is available here.
Demo version: Different lists->Change header name. After clicking "Column 2 visible" check box "Number 2 column" disappears or reappears.

Remember feature
Entering data is very dull task but "remember feature" provides some relief. Just restores value used last time. So far it could be achieved programmatically but from now on it is done automatically by adding "remember" attribute to a field description. Value can be remembered for each field individually or several fields can share the same value. More detailed description is available here.
Demo version : Alerts -> Dialog with remember.

Fields "Remember us" shares the same remembered value.
Suggest feature
"Remember" recalls only one last value but "Suggest" brings back a list of values to choose from. To implement "Suggest feature" GWT SuggestBox widget is used. Suggest list can be static or dynamic. Static gives the same list of predefined values all the time. Dynamic is enhanced automatically, every time user enters new value it is added to the list. In case of overflow the oldest value is removed. List can be stored individually for each field or the same list can be shared between different fields. More detailed description is available here.
Demo version :  Alerts->Dialog with suggest.

"Suggest custom" is using a static suggest list and "Suggest" dynamic
Get data
Data from any list can be downloaded or send to the recipient. Just click: "Tool" -> "Get data".


Several formats are supported: cvs, xml, html, JSon and PDF.

niedziela, 1 lutego 2015

New version of JavaHotel, taxation

Introduction
I uploaded new version of JavaHotel application. Demo version (U/P user/user) is available here, source code here.
Taxation
While issuing a document (receipt, bill) a taxation is calculated using tax level assigned to the service.

Detailed information related to the document is also available. This information if stored in the database (as XML file) for every document issued.
Taxation information is also exposed in "Stay summary" window providing information about the current status of the stay.
Next step 
Receptionist journal registering the information about user activity.

niedziela, 16 listopada 2014

New version of JavaHotel application

Introduction
New version of JavaHotel application is deployed to Google App Engine (User/Password user/user). Source files are available here.
Changes implemented:
  • Visualization of the reservation state in the reservation panel
  • Advance deposit for guaranteed booking
  • More convenient to work with reservation
  • Confirmed/Not confirmedbooking
  • Access to the reservation data from the list of reservations (not only from reservation panel).
  • Warning before making the reservation persistent without refreshing it.
Visualization of the reservation state

The following states are recognized:
  • Reservation scheduled (not confirmed)
  • Reservation confirmed
  • Reservation, advance deposit paid by the customer
  • Reservation, advance deposit payment date expired
  • Customer not arrived. Current date is greater then the beginning of the reservation  and no check-in yet
  • Vacant, not paid. Last day of the stay expired and the bill is not balanced
  • Vacant. Last day of the stay expired and fully paid
  • Vacant excess payment. Last day of the stay expired and the payment exceeds the bill
  • Occupied, not paid.
  • Occupied, advance paid. Advance deposit payment exceeds the bill still
  • Occupied paid
  • Occupied excess payment (including advance deposit)
Advance deposit for guaranteed booking
During making the reservation an advance deposit can be specified.

 The advance deposit amount can be entered directly or calculated automatically as a percentage of the total payment. The advance deposit payment date can be specified also.
Important: Current version supports advance payment only as an additional information for the operator. No automatic action is performed.
The advance deposit data can be specified also later by changing the existing reservation.

The dialog allows also to enter payment done by the customer.

More convenient way of working with the existing reservation
After clicking the reservation in the panel a smaller windows pops-up.
This window allows simpler access to some functionality related to the reservation. After clicking on "Change reservation" the full reservation dialog is displayed.
Confirmed/not confirmed
Reservation can be marked as confirmed/not confirmed. This indication can be specified at the beginning and can be modified later. Important: confirm/not confirmed status is only for an information, no automatic action is implemented.
Access to the reservation data also from reservation list
"Administration" -> "Reservations"
List of reservations displays also reservation status. After clicking the column the reservation (or stay) details are displayed. It is the same dialog window as in the reservation panel. Also reservation (or stay) modifications can be done here.
Warning before making the reservation persistent
Reservation (also modification) should be done in three steps:
  1. Fill reservation data (number of days, number of persons, price list etc)
  2. Refresh the reservation. It applies reservation data entered in step 1 and recalculates it. Also checks if reservation does not overlaps with other reservation. 
  3. Make reservation. It makes the reservation persistent. Uses the result of the last refreshing. So if user omits step 2 the final result can be different then expected.
In order to  minimize the risk of confusion a warning window is displayed signalizing that some changes were made without refreshing the reservation.



The user can finalize reservation (ignoring changes) or return to the booking dialog.

Next steps
  • Taxation
  • Reports

wtorek, 23 września 2014

New version of JavaHotel, mailing

Introduction
I deployed new version of JavaHotel application. Google App Engine demo is available here (U/P user/user), source code can be downloaded here. New feature is mailing.
Booking
Sending a confirmation mail is a part of the booking process. After successful booking confirmation note can be sent immediately.

If answer is yes then a window with note content pops up.

The note content is generated automatically through XSLT transformation. XSL source file is available here. By extending XSL source file it is possible to modify the confirmation note content: add some graphics, information about cancelation policy, payment method etc. Note content can be also modified manually before sending.
Confirmation email can be sent also later or resent again in case of reservation changing.


Mailing PDF receipt
Automatic mailing is enabled for PDF receipt. Hotel guest can ask for a second copy of the receipt after leaving the hotel or wants to make some changes in the receipt content (for instance address data).
The receipt PDF is attached to the note. The content of receipt note is also generated using XSLT and can be modified as desired.

Email collecting
All notes sent from the application are stored internally in the database (independently from 'Send' folder in the mail box).
The user can review all notes related to the particular reservation.


Also all notes sent to the customer/guest can be reviewed.


Next step

Advance payment.

wtorek, 26 sierpnia 2014

MVP Jython framework and mail handling

Introduction
I deployed a new version of MVP framework containing mail handling. Google App Engine demo version is available here (Mail ->Send mail (save)). The purpose is not to create another mail client but to provide simple Jython interface for mail sending (cmail.py). The solution also stores mail sent in the database for future reference.
This interface will be used later in JavaHotel application for tasks like: reservation confirmation, invoice sending etc.
In JEE version JavaMail is used, in Google App Engine Mail Java Api is used.
Test GUI
Sample application contains GUI for testing purpose, a sample usage of cmail.py interface. The test code is available here.
List of mails sent (taken from database, not from 'Sent' folder).


Mail sending (with attachment)
List of attachments from note already sent
Future
Apply the solution is JavaHotel application.

niedziela, 29 czerwca 2014

JavaHotel, new version

Introduction
I deployed next version of JavaHotel application. Demo version (Google App Engine) is available here (U/P user/user) and source code here.
Searching
I added a searching (so far new reservation was activated after clicking in the hotel room/day cell).
After clicking "Search" button a list of hotel rooms available is displayed :
and the user can select a room and a reservation can be started.
Reservation extension
After reservation is booked it is possible to extend it by adding another room to the reservation or extend the reservation period for the room already booked.  This option is available after clicking "Extend reservation" button.
 It is the same searching mechanism as above but after clicking "Add to reservation" button the room selected is added to the existing reservation.
Reservation modification
Also more detailed modification of existing reservation is possible after clicking "Modify reservation" button.

The user can modify reservation for the single day/room line, remove one line from the reservation and add a new line.
Customer/guest info
This option is available through "Upper menu" -> "Administrator" -> "List of customers" -> "Info".
This window shows the activity of the particular customer.
Room/service info
"Upper menu" -> "Administrator" -> "Services" -> "Modify" -> "Show rooms"
List of hotel rooms sharing this service.
Additional changes
  • Modifying list of guests (checked in) also during a stay.
  • "Administrator" - blockage for removal objects (rooms, customers, services, price list) if there exists any dependent object (for instance: cannot remove a hotel room if there is exist a reservation for this room). Future: add option "out of use" or "deactivate" the object.
  • "Spinner" widget (look above) to make user interface more user friendly.
Next step
Implements charts (I'm going to use Google Charts ) to visualize room, service or customer activity.

środa, 21 maja 2014

JavaHotel, Jython 2.7 and Google App Engine

Introduction

I decided to go ahead and upgrade Jython I'm using from Jython 2.5 (Jython 2.5.4rc1) to Jython 2.7 (Jython 2.7beta2). It works without any problem but I was stuck after deploying to Google App Engine.  The exception error was as follows:

Caused by: java.lang.ExceptionInInitializerError
 at jnr.posix.POSIXFactory.(POSIXFactory.java:15)
 at org.python.modules.posix.PosixModule.(PosixModule.java:63)
 at org.python.modules.Setup.(Setup.java:29)
 at org.python.core.PySystemState.initBuiltins(PySystemState.java:1317)
 at org.python.core.PySystemState.doInitialize(PySystemState.java:1056)
 at org.python.core.PySystemState.initialize(PySystemState.java:982)
 at org.python.core.PySystemState.initialize(PySystemState.java:938)
It was very nasty because it worked in Development Mode (local environment) and it is not easy to debug the application after deploying to the production environment.

Solution 

After spending some time, analyzing exception stack and digging through different versions jnr-posix module (used by Jython for system related stuff) especially Platform class I found the solution.  It was because Google App Engine does not set os.name property (it is null). So the solution was to enhance appengine-web.xml file.
  <system-properties>
    ......
    <property name="os.name" value="linux"/>
    <property name="os.arch" value="amd64"/>    
  </system-properties>
It works now but two questions are pending around me:
  • How it worked with Jython 2.5
  • While Google App Engine set this variables in Development Mode and does not set in Production Mode.

piątek, 9 maja 2014

Glassfish to JBoss (WildFly) migration

Introduction
I decided to migrate JavaHotel application to WildFly (former JBoss) keeping Glassfish version still alive. The reason was very simple. I was unable to call remote EJB deployed to Glassfish. It works from another Glassfish, also from Java standalone application  (following instructions under this link) but I failed to call EJB from another web container (Tomcat or Jetty). I tried to follow instructions from this blog. But the list of jars is valid for Glassfish 3.0, in 4.0 the jars are different and after spending a lot of time combining different sets of jars I finally gave up and switch to WildFly. I was successful but had to overcome some problems related not only to migration from one web container to another but also related to migration from EclipseLink JPA to Hibernate JPA.
Last but not least - to call remote EJB deployed to WifdFly server it is enough to add jboss-client.jar to classpath regardless of the client type.
I'm ignoring trivial tasks related to migration like: data source migration, EJB addressing, JNDI variables etc.
Several persistence-units in the single persistence.xml
Problem
I used to have a single persistence.xml file containing all persitence-units I'm using in different configurations. For instance "RESOURCE-LOCAL" persistence-unit for Tomcat and "JTA" fo JEE container. EclipseLinks at the moment of invoking Persistence.createEntityManagerFactory reads only persistence-unit requested, Hibernate reads the whole content of persistence.xml just failing if any of the persistence-units cannot be initialized.
Solution
Very simple : just split the single persistence.xml into several containing only persitence-unit necessary in the given context.
Different strategies for @Id @GeneratedValue(strategy=GenerationType.AUTO)
Problem
EclipseLink and Hibernate use different strategies for generating global object IDs. EclipseLink creates a separate table (sequence) and Hibernate JPA uses sequence hibernate_sequence (checked for Postresql and ApacheDerby). So after switching from one framework to another on existing table one can run into trouble (duplicate primary key) when both methods overlaps. It costed me a lot of time to discover the problem.
Solution
Use different @GeneratedValue strategy or do not switch framework.
@Lob column for PostgresSql
Problem
@Entity
public class LobRecord implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    @Lob
    private byte b[];

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @return the b
     */
    public byte[] getB() {
        return b;
    }

    /**
     * @param b the b to set
     */
    public void setB(byte[] b) {
        this.b = b;
    }
    
}
Unfortunately, Postgresql does not have direct BLOB or LOB column type. EclipseLink translates the @Lob column to bytea (what I expected) but Hiberbate generates oid column type which causes a lot of trouble.
Solution
There is no universal solution to this problem.
  1. Remove @Lob annotation. Both EclipseLink and Hibernate generates bytea column type. But after removing this annotation for ApacheDerby this column is generated as VARCHAR () FOR BIT DATA (not BLOB) which is not valid
  2. Add direct specification @Column(columnDefinition="bytea". But it will not work for ApacheDerby (or any other database, it is PostreSql specific)
  3. Adjust annotation any time database or framework is changed. 
Hiberate does not like hierarchical references in DELETE command
Problem
@Entity
public class CountryRecord implements Serializable {
....
}

@Entity
public class ProvinceRecord implements Serializable {
...    
    @JoinColumn(nullable=false)
    private CountryRecord country;
}

@Entity
)
public class CityRecord implements Serializable {

...
    @JoinColumn(nullable = false)
    private ProvinceRecord prov;
...
}

@NamedQueries({
    @NamedQuery(name = "removeCities", query = "DELETE FROM CityRecord r WHERE r.prov.country= ?1")
p.country= ?1)")
}

EclipseLink does not complain but Hibernate throws an exception
ERROR: HHH000177: Error in named query: removeCities
org.hibernate.QueryException: could not resolve property: country of: teste.entity.CityRecord [DELETE FROM teste.entity.CityRecord r WHERE r.prov.country= ?1]
 at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)
 at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:77)

What is more intriguing - Hibernate has nothing against this type of hierarchy in SELECT statement.
Solution
Replace hierarchical reference by nested SELECT.
@Entity
@NamedQueries({
    @NamedQuery(name = "removeCities", query = "DELETE FROM CityRecord r WHERE r.prov in (SELECT p FROM ProvinceRecord p WHERE p.country= ?1)")
}

Hibernate does not like duplicated named query

@Entity
@NamedQueries({
    @NamedQuery(name = "removeCities", query = "DELETE FROM CityRecord r WHERE r.prov in (SELECT p FROM ProvinceRecord p WHERE p.country= ?1)"),
    @NamedQuery(name = "removeCities", query = "DELETE FROM CityRecord r WHERE r.prov in (SELECT p FROM ProvinceRecord p WHERE p.country= 
}

EclipseLink accepts it.  
Different default column naming for class references
Problem
@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = { "name", "company" }))
public class PersonRecord implements Serializable {


    private String name;

    @JoinColumn(nullable = false)
    private CompanyRecord company;
,,,,
}

It works for Hibernate but failed for EclipseLink. This is because Hibernate generates company as column name for company reference class but EclipseLink generates company_id column name so the unique constraint fails. After replacing company with company_id in the UniqueConstraint annotation the result is opposite.
Solution
Unfortunately, Hibernate ignores name parameter in JoinColumn annotation. To redefine column name it is necessary to add Column annotation. But EclipseLink does not accept both JoinColumn and Column annotation for the same field. So the only solution for both frameworks is to add name parameter to JoinColumn annotation which is ignored by Hibernate but works for EclipseLink
@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = { "name", "company" }))
public class PersonRecord implements Serializable {

    private String name;

    @JoinColumn(nullable = false,name="company")
    private CompanyRecord company;

Different resource filepath
Problem
Assume we want to deploy a simple .war to web container containing  resource/param.txt and want to read this file.
That's pretty simple just:

public class Listener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("Start");
        URL u = Listener.class.getClassLoader().getResource("resource/param.txt");
        System.out.println("U=" + u.getFile());
...
But sometimes is was convenient for me to read this file using :

InputStream i = u.openStream 
and sometimes to read this resource like regular file in the file system using getFile method.
There is no problem on all webcontainers (even Google App Engine infrastructure). For instance, on Tomcat getFile() method returns:

U=/home/hotel/.netbeans/8.0/apache-tomcat-8.0.3.0_base/webapps/ReadRes/WEB-INF/classes/resource/param.txt
But on WildFly it returns something like:
U=/content/ReadRes.war/WEB-INF/classes/resource/param.txt
It does not reflect the place where resource is unpacked, it should be something like:
.../{standalone}/tmp/vfs/temp/temp577a2348203a1442/content-34f69a82c7d2649f/WEB-INF/classes/resource/param.txt
Solution
Of course, it is necessary to read resource file using OpenStream (or any other method) and read file in the file system using file path. 
But I cannot use it for Jython code deployed as a resource which needs file path and there is no simple way to overcome it. The only solution is to deploy Jython code outside .war file and use directory file path.

czwartek, 24 kwietnia 2014

Java Hotel, new version, printing and pdf generating

Introduction
I deployed new version of JavaHotel application to Google App Engine infrastructure. The version is available here and source code for all application is available here (U/P user/user). This version contains PDF generating for bill issued and receipt printing (from PDF). It is also possible to save PDF created and reprint it later.
PDF generating
After issuing a bill there is a "print" button in the bill list. After clicking the button a html preview of the receipt is presented (it is very rough now, requires more elaboration for real use).
The user can download the PDF (after clicking the receipt.pdf link) and print and save PDF with description for later reuse
The PDF is generated from the HTML view.

If PDF is saved then it is available for later reuse. More the one PDF can be saved for a single bill (for instance in case of correcting) to keep all documents given to the customer.

The user can download and print again the PDF and edit the description.
How it is done
The receipt (as HTML) is generated through XSLT transformation. An example used here is available here. It is very convenient and allows to align receipt form without modifying the application. It is also possible (will be implemented later) to use more then one receipt format for different customers and services.
PDF is generated from HTML by means of iText software.
XSLT and Google App Engine
After deploying the application to Google App Engine I spent some time fighting with (in Development Mode worked correctly):
transformer = tFactory.newTransformer(StreamSource(iS.openStream())) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.defineTransletClasses(TemplatesImpl.java:352) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:366) at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:399) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:634) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:45) javax.xml.transform.TransformerConfigurationException: javax.xml.transform.TransformerConfigurationException: Translet class loaded, but unable to create translet instance.
After applying the solution described here (deploy all jars related to xalan) the problem was resolved.
Glassfish 4.0 and GWT 2.6
I spent also some time working with problem related to Glassfish 4.0 (the same for WildFly-JBoss) and GWT 2.6
Severe: Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [Set] with qualifiers [@Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] @Inject com.google.gwt.thirdparty.guava.common.util.concurrent.ServiceManager(Set)] org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Set] with qualifiers [@Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] @Inject com.google.gwt.thirdparty.guava.common.util.concurrent.ServiceManager(Set)] at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:403) at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:325) at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:177)
The problem is related to Guava rather but because the Guava seems to be included in gwt-servlet.jar so the problem was inherited accordingly. I'm using also Guava but before 2.6 I utilized Guava embedded in Glassfish.
The hot discussion around this issue is available here.
The problem disappeared after applying the solution described there.

  1. Prepare beans.xml file:
  2. <beans bean-discovery-mode="none" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee"></beans>
  3. Unpack standard gwt-servlet.jar 
  4. Put this file into META-INF directory 
  5. Pack gwt-servler.jar and use it instead of original one.

czwartek, 2 stycznia 2014

JavaHotel - customer/guest description improved

I deployed new version of JavaHotel application. English and Polish version is available as Google App Engine application. Also J2EE version (Tomcat and Glassfish) has been created. The main enhancement is the more extensive customer description.

Also Polish version is available having localized messages and dictionaries and some smaller improvements.

niedziela, 22 grudnia 2013

JavaHotel - reservation panel improved


New version of JavaHotel has been uploaded (U/P user/user). The main difference is improved reservation panel : more compact, better navigation and better visualization of reservation.


The main challenge I fought with was adding colspan to CellTable. After spending a lot of time trying to apply different methods I ended up with copying and pasting DefaultCellTableBuilder and adding necessary changed to the underlying algorithm.

wtorek, 15 października 2013

JavaHotel, first version

First version
I uploaded the first version of JavaHotel to Google App Engine. Test version is available: Java hotel for user (U/P user/user) and Java hotel for administrator (U/P admin/admin). Source files are available here. It is Google App Engine version but I'm planning to use it only for demo purpose. Also regular JEE version is created as a primary target. It will be available for Tomcat and Glassfish. Tomcat version is a single web application, Glassfish version is divided into persistence layer available as Session Stateless Bean and business logic layer. It was tested with Derby, Postgress and DB2.
It is the first version and everything is rough. But basic functionality is covered.
  • Prepare database: hotel, users, room, services, pricelist
  • Reservation panel
  • Booking
  • Check-in
  • Registering additional services during the stay
  • Billing
Reservation panel

Empty places denote free rooms, green booked and yellow with guests currently checked-in. Clicking at the empty place allows to make reservation starting from this day forward, clicking at the green allows to make check-in if customer just arrived and clicking at the yellow gives access to options related to stay (for instance: billing)
Reservation

It is the reservation dialog available after clicking at the empty room. User can modify number of days (default is one), calculate rating and enter the customer data. It is also possible to select the customer from the list of customers already registered.
Check-in
Check-in dialog pops up after clicking at the green (reservation) place. It allows transforming reservation to stay and starting billing the guest. In the check-in dialog it is also possible to register additional guests if the booking was done for more then one person.
Registering additional services

After stay has been started it is possible to append additional services to the stay. User can select a standard service prepared before or add a new services ad-hoc.
Billing
During and after the stay a bill can be issued. It is possible to issue more then one bill for one stay and every bill having a different payer. In the tab panel 'Not paid yet' page contains services not paid yet (without the bill issued for them) and 'All billable' contains the list of all services. The payment can be specified as 'Pay now' or 'Not paid now'. There is also possibility to register payment later for bills not paid now.
Conclusion
It is the first version so everything is basic and rough. But the most important functionality is implemented already. Next steps:

  • Booking of more then one room,  searching. For instance: implement scenario like: "Find the first available reservation for 5 persons: two double rooms and one single".
  • Issuing and printing the invoice.
  • Synchronization with calendar. Alerts when reservation or stay expires. 

niedziela, 22 września 2013

MVP framework, new features

Introduction
I added several enhancements to the MVP Jython framework. Source code is available here, sample application developed for Google App Engine can be launched using this web URL.
New types of main menu
So far only left side list of button has been available. Two new types of main menus have been added: "Up" menu and stack menu. "Up" menu is nothing more then image at the top status bar which expands after clicking giving a list of choices. Stack menu is an implementation of GWT StackPanel. "Up" menu can coexist with tab menu and stack menu but stack menu and tab menu excludes each otther. An example of stack menu is available here. More technical description.
"Up" menu

Stack menu














Image column
Image column contains icon or list of icons instead of text or number. Image list can be static or dynamic. In the second case a JavaScript code is executed to determine the list of images displayed depending on the row content. More detailed description. Icons plays also a role of buttons. After user clicks the icon a Jython server side action is raised. This way it is possible to implement an action depending on the row content and which icon has been clicked.

A running example is available here. Click "up" menu -> "List with icon". The up arrow is displayed for positive number and down arror for negative number. Left and right arrow is displayed depending if number is odd or even.
Different type for column and footer
As a default the footer type (and other properties like align and decimal position) are copied from column type. But it is possible to change this behavior.


A running example is available here. "Status" -> "List footer". The footer is under string column but the footer content is a number. Also align schema is different. More detailed description is available here.
Other changes
  • Dynamically modify the content of the status bar. The the status bar content can be customized depending on the context. More detailed description is available here. Running example can be launched. "Status" - > "Status text".
  • Load tab panel page on demand. An action is raised after clicking the page header. This way the tab panel page can be modified dynamically. More detailed description.
  • XML usage. XML format is often connected with love-hate relationship. But it is very convenient if data schema is not stable or can be changed. It is also very convenient if we want to pack a lot information in one entry without creating a table with tens or hundreds of columns. So I added some automation for packing and unpacking forms using XML file. More information is available here.  A running example (although nothing spectacular is visible) can be launched here. Click on "Dialog base xml".