The Travelcost App — An Oracle JET Success Story

We at enpit are frequently on the road in order to reach our customers in all of Germany. Although traveling for work purposes can be interesting and refreshing, someone has to pay for it , which is what travel expenses are for. There is a multitude of apps in the app stores that promise to ease the burden of creating and handing in travel cost reports, but we have not been satisfied with those. Which is why we decided to create our own application for that purpose in 2016 — the Travelcost app was born.

In this story, we want to share a few of the key technical aspects of the app and its development process. As we are very happy with the result and how we implemented it, we even dare to call it a success story.

Create travel cost receipts on mobile or web — printing is optional.

The Requirements

As we were beginning to dip our toes into Oracles JavaScript Extension Toolkit (JET) and wanted to gather experience for bigger client projects, we decided to implement Travelcost in JET. There were three main requirements for the application:

  1. Allow the user to easily create a digital travel cost report, with as few clicks as possible and automatic travel cost calculation based on applicable law in Germany.
  2. Give the user the possibility to create a PDF report from their travel cost report, such that it can then be sent via Email to accounting, or printed and handed in the old-fashoined way.
  3. Optimize the web app for mobile, as it is somehow the custom at enpit to create the travel cost reports on a mobile phone at the end of the month when in the train back to Paderborn.

The Application

We invite you to use Travelcost on our enpit.de site (beware it’s in german though ;) ). The app starts at the home screen which displays a few exemplary travel entries for the guest user. When using the app in production, we log in using our Google account in order to just see our own travels; the guest account is mainly for demo purposes. Tapping/clicking “Neue Reise” opens up a new form for creating a new travel, and selecting an existing entry opens up a detail view for that travel. This is where travels can be edited, deleted, printed or copied (turns out a lot of our travels regularly repeat, so we do not want to insert all the same data again).

The home screen in a mobile web browser.

Generating PDF Reports

One very important feature is generating PDF reports. We chose pdfmake for rendering PDFs on the client side (we ultimately want the PDF on our client, and sending them over the internet wastes data, right?). Turns out this was a bad choice for two reasons:

  1. pdfmake has quite a few bugs on various mobile browsers, which resulted in frustration as the PDFs were not downloaded or not rendered correctly.
  2. The font file that accompanies pdfmake is 1MB large and cannot be compressed further — we would have to send a lot of PDFs, which are only a few KB in size, in order to make up for that.

This resulted in poor user experience due to long initial load time and unreliable rendering, which is why we decided to move PDF creation to the backend instead. This was an easy win as the client-side code that generated the PDF could be reused 1:1 (pdfmake also runs on nodejs after all). The results were extremely satisfying: Generating and downloading the PDF now takes under two seconds on 3G, and we reduced the footprint of our application by ~1.2MB. If there is a lesson to learn here, it is this:

Don’t solve in your frontend what is better solved in the backend.

We chose Heroku as a platform for running our backend services, which turned out to be an excellent choice. We have implemented three backend services, all in node.js, and were very pleased with the flexibility and usability of Heroku. We set our services up using the free dynos, which has the limitation that the services go into sleep mode after some inactivity, resulting in a delay of a few seconds when waking them up again by making a request. When we got serious about running the app in production, we switched to “hobby” dynos — which, to be honest, does not sound that serious as well. The hobby dynos do not have the sleep mode limitation any more, and can be upgraded further if need be.

For convenience, you can directly print a receipt for a travel upon creating or modifying it.

Continuous Deployment

As we wanted to treat the Travelcost app as a first-class project right from the beginning, we introduced linting and testing during the very early stages of the project (I blogged about how you can setup a linter in JET on our enpit-publication last year). We configured a build & deploy pipeline on Codeship, which builds the project, runs all tests and deploys the new version of the app or of the specific feature on Amazon AWS. This allows us to test each branch of our application individually — feature and bugfix branches all get their own URL with the respective feature or bugfix prefix, while the development and master branches are deployed to separate URLs. A push to master denotes a new release, so it also gets deployed automatically to enpit.de/travelcost. With this setup, getting feedback on a work in progress feature is as easy as pushing the current state to the feature branch and posting the URL to Slack:

Posting URLs to specific builds for easy testing.

However, automatic tests are boring if the developer who screwed the tests up is not blamed on Slack, so we setup the Codeship build notifier to report the build status. All kidding aside, this is pretty great because the whole team is kept in the loop about the development progress, and if the build fails you can get the conversation started right away in order to find a solution together.

The Codeship build notifier posts all results back to Slack — especially the bad ones.

Going Paperless

Although we now have a nice app that enables us to create travel report PDFs with ease, someone still has to invoice those reports. Instead of printing the reports on paper and handing them in manually 20th-century-style, we can send them via Email to Fastbill. This allows our accounting people to be more efficient by setting up filters, preprocessing of emails and other magic.

Future Plans

Although we have a public release of Travelcost now, we still have some future plans for it. The most exciting aspects are:

  • Releasing a Travelcost app built via Cordova on the Apple and Android app stores.
  • Offering multi-language support.
  • Implementing a Travelcost chatbot (e.g. for Slack) and a voicebot (e.g. for Alexa) which allows for even easier generation and management of travel cost reports.

The Verdict

We are very pleased with our release and excited about the future plans for the Travelcost app. Although the road towards the release was sometimes bumpy (for example when a new JET version was released), JET proved to be a very well-rounded toolkit for creating such an application and we learned a great deal during development.

Again, please try the app by yourself on our enpit-website and feel free to give us some feedback, preferably using the feedback button at the bottom of the app. You can visit the Travelcost info page for mor information if you speak some german. Also, make sure to visit us on Twitter or our website for more JavaScript and IT modernization expertise!