Skip to main content
Version: 2.0

Expense App Tutorial

note

This tutorial goes straight to the point. If you want to get more context around what you are doing, take a look at our Guided Overview, or to our DRAW Reference Guide.

The goal of this tutorial is to create multi-screen app with Olympe DRAW. It consists in a basic Expense App where a user can create new expenses with basic details, take a picture of the receipt and then consult the expenses created. You can find the final result in the Examples / Expense project.

We will build the app as follows:

  • We start by creating the data model to store our expenses.
  • We then add some logic bricks to make it easy to manipulate our expenses.
  • We then move to the UI and build the various screens.

Folder

1. Project

Let's start by creating a project that will contain our Expense App.

Folder

  1. Create a Project and name it Expense and open it.
  2. Create the following Folders:
    • Data
    • UI

2. Data

2.1 Data Model and Enums

Expenses will need to be created and stored. Our expenses will have a description, an amount, a currency and a picture of the receipt. Let's now create a data model to describe our expenses, together with an Enum for currency.

The currency is a bit different, as it is taken from a list of possible values (CHF, EUR, ...). We therefore need to describe it as an Enum.

  1. In the Data Folder, create a new Enum and rename it Currency.
  2. Click on the New Enum button, rename it to "Currencies" and add the following Values to the Enum from the New Value button:
    • Value = CHF and Display Name = CHF
    • EUR and Display name = EUR
    • USD and Display name = USD

Let's now create a Data Model to describe our expenses.

  1. Open the Data Folder.
  2. Create a new Data Model and rename it "Expense Data Model" and double-click to open it.
  3. Create a new Data Type and rename it "Expense".
  4. Add following Properties to Expense Model by drag&drop from the Marketplace:
    • "String" brick and name it "description";
    • "Number" brick and name it "amount";
    • "Currencies" brick and name it "currency".
  5. Add a "File" brick from the Marketplace under Relations and rename it "picture".

The end result should look like:

Data Model

Enum

3. Data Logic

Now that we have defined the data model for our expenses, we can think about how we will manipulate those expenses: they need to be created, updated, displayed, etc. To make it very easy to perform those activities once we get to the UI, we create a few helper functions and actions (also called constructors, getters and setters in standard programming terminology).

3.1 Create Expense Action

Let's start with an action to create a new expense. In a nutshell we need to:

  • Define the inputs we need to create the expense.
  • Create the expense and persist it (i.e. save it in the database).
  • Set the description, amount and currency and finally save it in the database.

Hopefully, DRAW will make most of the job for us.

Create Expense

  1. Go back to Data folder.
  2. Open the "Expense Data Model".
  3. On "Expense" model, click on the 3 dots icon to open the contextual menu.
  4. Click on "Generate helper bricks and forms".
  5. Click on the "Save" button.
  6. Select "Constructor" and unselect "picture".
  7. Click on Continue.
  8. Once the bricks are generated, click on Close.
  9. Go back to Folder "Data" => A new brick named "Create Expense" was generated.

3.2 Get Expense's Attributes Function

We now create a helper Function to make it easy to retrieve the Expense's values.

  1. Go to Data folder.
  2. Open the "Expense Data Model".
  3. On "Expense" model, click on the 3 dots icon to open the contextual menu.
  4. Click on "Generate helper bricks and forms".
  5. Click on the "Save" button.
  6. Select "Getter".
  7. Click on Continue.
  8. Once the bricks are generated, click on Close.
  9. Go back to Folder "Data" => A new brick named "Get Expense's attributes" was generated.

Get Expense's Attributes

3.3 Set Expense Picture Action

We now create an Action to attach the picture of the receipt to the expense.

  1. Go to Data folder.
  2. Open the "Expense Data Model".
  3. On "Expense" model, click on the 3 dots icon to open the contextual menu.
  4. Click on "Generate helper bricks and forms".
  5. Click on "Save to Data" button.
  6. Select "Setter" and unselect every property except "picture" (see screenshot below).
  7. Click on Continue.
  8. Once the bricks are generated, click on Close.
  9. Go back to Folder "Data" => A new brick named "Set Expense's attributes" was generated.
  10. Click on the 3 dots icon for the "Set Expense's attributes" and rename the brick to "Set Expense's picture".

Get Expense's Attributes

3.4 Format Expense function

We now create a helper function that will return a summary of the expense, including the currency, the amount and the description (e.g: USD40-Description).

  1. Go back to Data folder.
  2. Drag&drop a Function brick to create a new Function. Rename it "Format Expense" and double-click to open it.
  3. From the top-left corner, click on the "Add input" button, name it "expense" and set type to Expense from the drop-down list. Click on Add.
  4. Search in the Marketplace for "Get Expense's attributes" brick and drag&drop it into your function.
  5. Connect the function input "expense" to "Get Expense's attributes" Object input.
  6. Search in the Marketplace and add a "Concat" function brick to concatenate the following texts:
    • Connect the "currency" output of "Get Expense's atrributes" to s1;
    • Connect the "amount" output of "Get Expense's attributes" to s2;
    • Add another "Concat" brick;
    • Connect the output of the first Concat brick (s1+s2) to s1 of the newly added Concat;
    • Click on the "s2" input of the second Concat brick and type "-" as a Constant;
    • Add a 3rd Concat brick and connect the output (s1+s2) of the 2nd Concat to s1;
    • Connect "description" output from Get Expense's attributes to the s2 input of the 3rd Concat brick;
  7. From the top-right corner, click on the "Add output" button, name it "summary" and set type to String from the drop-down list. Click on Add.
  8. Connect output of the 3rd Concat brick to the output of summary.

The end result should look like this:

Set Expense

4. UI

We have now defined the data that we will be managing within our application, as well as some helper functions to simplify the manipulation of those data. Similarly, there are some UI components that will be reused across all several screens, so designing them once and for all allows us to reuse them with minimal effort.

4.1 Header

Our app has a Header, which we see on every screen. In order to avoid creating it from scratch on each screen, we now create a reusable UI Component, which we will then be able to drag and drop every time we need it.

Header

  1. Go back to Project and open the UI folder.
  2. Search in the Marketplace for "Visual Component". Drag&drop it to create a new Visual Component. Name it "Header" and double-click to open it.
  3. In the Layers's tree, click on the "Header" to select it.
  4. In Properties Panel, click on the 3rd tab. Under Background, set "Color" to black".
  5. Drag&drop a "Button" Visual Component and configure its properties as follows:
    • 1st tab: Text = "< Back"; Variant = "Outlined"
    • 2nd tab: X = -6, Y = Middle (select from the drop-down arrow), Width = 85;
    • 3rd tab: In Advanced Styling, let's add some CSS code: "border-style: solid solid solid none";
  6. Drag&drop a "Label" UI Component, rename it as "Header title" and configure its properties as follows:
    • 1st tab: Text = "Title"; Text Variant = Heading 5; Horizontal Align = "Center"
    • 2nd tab: X = Center, Y = Middle (select from the drop-down arrow);
  7. Drag&drop a "Rectangle" and configure its properties as follows:
    • 2nd tab: X = Left, Y = Bottom, Width = 100%, Height = 6
    • 3rd tab: Background color = select the predefined grey

Header

The text of our button and title will not be the same on all screens. Similarly, when we click on the header different things may happen depending on the screen. We therefore want to be able to customise our component a little bit each time we use it. This is done in four steps:

  1. Define a Context.
  2. Set the value of the title.
  3. Determine whether the Back button is visible or not.
  4. Trigger an event from the Back button when we click on it.

1. Define the Context of our Visual Component

Each Visual Component (and screens as well by the way) can have a Context, i.e. a set of parameters and events that are available from outside the component. In our case, we want to configure the Header Button visibility and the Header Title text. Also, when the button is clicked, the component must notify its parent.

On the top of the Editor, click on "Spec & Doc" tab.

  1. Add two "Property" bricks by clicking on the "New" button with the following:
    • Name the first property "Hide Button". Select the Type = Boolean from the drop-down list;
    • Name the second property "Title". Select the Type = String from the drop-down list;
  2. Add also an "Event" and add the following:
    • Name it "On Back".

Header Context

2. Set the text of the Title

On the top of the Editor, click on "Visual Editor" tab.

  1. From the Layers's tree, select the "Header title" label.
  2. In properties panel, 1st tab, under "Text", create a function by clicking on the f(x) button and configure it as follows:
    • At the left of the screen, under Property Picker, drag the "Header" component and drop it to the Function body (empty rectangle in the middle of the screen).
      • Search and select property "Title (String)" (that's the one created previously) and click on "Get Value".
      • Connect the "Get UI Property" Value output to Function Text output.
    • Close the function.

Set the visibility of Header button

  1. Go back to the Header's Visual Editor and select from the Layers's tree "Header button".
  2. In properties panel, 3rd tab, under Visibility, clik on the f(x) next to the "Hidden" toggle.
  3. Drag the "Header" component and drop it to the Function body.
    • Search and select property "Hide Button (Boolean)" and click on "Get Value"
    • Connect the "Get UI Property" Value output to Hidden output.
    • Close the function.

Raise the event when the button is clicked

  1. Go back to the Header's Visual Editor and from the Layers's tree, click on the "Header button".
  2. In the properties panel, 4th tab, create an action for Interaction "On Click" by clicking on the f(x) button and configure it as follows:
    • Drag&drop the "Dispatch Event" brick onto the screen from the Marketplace.
    • Connect Action Control Flow input to "Dispatch Event" Control Flow input;
    • Click on the "Event" input of the "Dispatch Event" and click on the Target icon under "Constant";
    • A new Editor will open. Click on "Header" in the Current's tree and select "On Back (UI Event). Confirm it by clicking on the "Dispatch" button.
  3. The screen returns to the Control Flow. Close the action.

5. App

5.1 Expense App

We have now built the plumbing for our application: we have a data model and helper functions to manipulate the data, and we have a reusable header component. Let's now create the Expense App and start plugging the different parts together.

Expense App

  1. Go back to the Expense Project.
  2. Search in the Marketplace for the "UI App" brick.
    • Drag&drop it to create a new UI App.
    • Name it "Expense App" and double-click to open it.

OPTIONAL: Run the app on another tab or on a mobile device using the two little buttons at the top-right of the editor next to the marketplace.

Run

5.2 Home Screen

Let's start with the Home screen of our app. The home screen consists in:

  • The header we built above;
  • A button to create new expenses;
  • A list of existing expenses with a button to open one and see its details.

Home Screen

  1. Double-click on the Home screen to open it.
  2. Search in the Marketplace for the "Header" Visual Component you just created and drag&drop it. Drag&drop also a "Button" and a "List" bricks.
  3. Click on the "Home screen" in the Layers's tree:
    • 1st tab: Layout = Vertical, Spacing = 60
    • Using the Layers's tree, reorder the elements to have the Header at the top by drag&dropping.
  4. Click on the "Header" in the Layers's tree, rename it as "Header" and configure it as follows:
    • 2nd tab: Height = 90, Width = 100% (using menu to switch to %)
    • 1st tab: Title = "My Expenses", Hide Button = True (switch the toggle)
  5. Click on the "New Button" in the Layers's tree, rename it as "New Expense Button" and configure it as follows:
    • 2nd tab: Width = 200
    • 1st tab: Text = "Create Expense"; Variant = Contained; Color = Primary; Font Size = Medium
  6. Click on the "New list" in the Layers's tree, rename it as "Expense List" and configure the list as follows:
    • 2nd tab: Width = 90%, Height = 570 (or if you feel confident, you can even define a function to make it grow automatically depending on the size of the screen!)
    • 1st tab: Item Width or Height = 60; Spacing = 10

Configuring the list of expenses

We now want to display the list of expenses. This is done in two steps:

  1. Get the list of expenses which we want to display.
  2. Configure each line of the list to display the expense as we want it.

Select the "Expense list" from the Layers's tree and configure it as follows:

  • 1st tab: Data = Click on the f(x) button to create a function which returns all Expenses using the "Get Object List" function. See screenshot below and the steps in doing so:
    • Search in the Marketplace for "Get Object List" brick and drag&drop it onto the screen;
    • Click on the "model" input and select "Expense" from the drop-down list;
    • Connect the "object list" output to the Data output.

Home Screen

And now we can display an expense in the list:

  1. Go back to the Home Screen.
  2. From the Layers's tree, click on "Expense List". In the 1st tab, click on the Item Renderer's Create button. This will define content to be displayed on each lines (Expense details).
  3. Add a new Label brick from the Marketplace and rename it "Summary" in Layers's Editor.
    • 2nd tab: X = Left, Y = Middle (selectable from the drop-down arrow);
    • 1st tab: Text: Create a function which returns the summary of the expense (see below image).
      • Click on the f(x) button next to the Text.
      • From the Prop picker's tree, drag&drop "Expense List_Item Renderer" onto the screen.
      • Select "Current Item (Object)" and confirm with Get Value button.
      • From the Marketplace, drag&drop the "Format Expense" brick.
      • Link the "Get UI property" output to the "Format Expense" input.
      • Link the "Format Expense" output to the orange Text input.
  4. Go back to the "Item Renderer" from the top menu. Drag&drop a Button, rename it as "View button" and configure it as follows:
    • 2nd tab: X = Right, Y = Middle, Width = 100;
    • 1st tab: Text = "View"; Variant = Outlined;
  5. Close the list item renderer.
  6. Back to the Item renderer view, let's add an Image brick.
    • 1st tab: Click on the f(x) next to the Image.
      • From the Prop picker's tree, drag&drop "List_Item Renderer" onto the screen.
      • Select "Current Item (Object)" and confirm with Get Value button.
      • From the Marketplace, drag&drop the "Get Expenses Attributes" brick.
      • Drag&drop the "Get First Object in List" brick.
      • Link the "Get UI Property" output to the "Get Expense's attrbiutes" input.
      • Link "picture" to the input of "Get First Object in List"
      • Link "Get First Object in List" output to the Image file.

Amount_in_list

You can find here an example on how to retrieve the current value of a list item renderer.

We will configure the "View" button a bit later in the tutorial. We need a few expenses to test that the list is properly configured. Before being able to create them from the application, we can create one or two expenses using the same Data Set that we used to create the currencies.

5.3 New Expense Screen

Now that we are done with the Home screen, let's look at the screen which we open when clicking on "Create an expense" button in the Home screen.

Before we design the new screen, let's create an Expense Form. Let's open the UI Folder from the main view of the Project. Drag&drop a Visual Component and name it "Expense Form".

  1. Add a "Dropdown" brick from the Marketplace.
    • 1st tab: Set "Values"'s tag to Currencies from the drop-down menu; Set "Label" = Currency.
    • 2nd tab: X = 0; Y = 5; Width = 100%; Height = 40.
  2. Add a "Text Field" brick.
    • 1st tab: Set "Label" to Amount; Type = Number;
    • 2nd tab: X = 0; Y = 55; Width = 100%;
  3. Add another "Text Field" brick.
    • 1st tab: Set "Label" = Description;
    • 2nd tab: X = 0; Y = 105; Width = 100%
  4. In the Spec & Doc editor, let's define a Property and some Events.
    • Add a Property called "Edited Object", with type Expense.
    • Add 3 Events: On Saved, On Error and Save.
  5. Go back to the Layers editor and select the Amount TextField component. Click on Value f(x) to define a function for retrieving the values for the amounts.
    • Drag&drop "Expense Form" and select "Edited Object", confirm with "Get Value".
    • Drag&drop from the Marketplace one "Get Object property" brick.
      • Set "property" to "Expense.amount"
    • Connect "Get UI Property" output to "Get Object Property" input.
    • Link "Get Object Property" output to the function's output.

It should look like this: expense_form_spec_doc

This is the New Expense screen. It consists in:

  • A header;
  • A text field to set a description;
  • A text field to set the amount;
  • A dropdown to set the currency;
  • A button to confirm and create the expense.

New_Expense_Screen

Let's first create the screen and make it reachable from our Home screen:

  1. Go back to Expense App at the Screen Flow Editor tab.
  2. Add a new Screen from the Marketplace and name it "Create Expense".
  3. Click on the arrow next to the Trash icon's Home Screen. Drag & drop towards the New Expense screen to create a transition between the Home screen and your new screen.
  4. Click on the dot in the middle of the transition to edit it.
  5. Next to "Event", click on the + button, this will display the home screen.
  6. Click on "Create an expense" button, select "On Click (UI Event)" and click on Dispatch.

If you have the app running you should be able to click on the button to go to your new screen. We can now add the different UI elements:

Open the new screen.

  1. In the 1st tab, set Layout = Vertical, Spacing = 50;
  2. Add a "Header" UI Component from the Marketplace and configure it as follows:
    • 1st tab: Title = "Create Expense"
    • 2nd tab: Height = 90, Width = 100%;
  3. Add the "Expense Form" from the Marketplace:
    • 2nd tab: Width = 80%; Height = 300;
  4. Add a Button brick from the Marketplace and rename it to "Create button":
    • 1st tab: Text = "Create";
    • 2nd tab: Width = 300;
    • 4th tab: Click on "On Click" f(x) and define the function as follows:
      • Drag&drop a "Dispatch Event" brick from the Marketplace;
      • Click on "Event" and in the constant, click on "New Expense Form" and select "Save (UI Event)" and confirm with Dispatch.
      • Link the function's Control flow to the Control Flow of Dispatch Event.

The screen should look like this: create_expense_screen

The final part is to actually create the expense once we click on the button. However, we actually need to do a bit more than that; clicking on the button has to:

  • Create the expense
  • Move to the next screen that will allow us to take a picture of our receipt
  • Make sure that the next screen has the expense that we are just creating, so that it can attach the receipt to it
  1. On the current view, click on tab "Spec & Doc ".
  2. Add a new "Event" and name it "On Create".
  3. Add a new "Property", name it "New Expense" and set type to "Expense".

5.4 Expense Picture Screen

So far, we have created a Home screen, as well as a New Expense screen that allows creating a new expense. What we now want to do is to take a picture of the receipt, and attach it to our expense. We do this in a new screen, which is displayed when we click on the "Create" button in the New Expense screen. Our Expense Picture screen therefore consists of:

  • A header
  • A video which displays the camera
  • A button to take the picture of the receipt. When the picture is taken, we go back to the Home screen.

Expense_Picture_Screen

Let's start by creating our new screen, and connecting it to the New Expense screen. We also need to make sure that the expense created in the New Expense screen is transferred to the Expense Picture screen so that we can link the two together.

  1. Go back to Expense App (Screen Flow Editor).
  2. Add a new Screen brick from the Marketplace, name it "Expense Picture" and open it by double-clicking it.
  3. Click on tab "Spec & Doc".
  4. Add a "Property", name it "Expense" and set type to Expense.
  5. Add an "Event" and name it "On Picture Taken".
  6. Go back to Expense App (Screen Flow Editor).
  7. Create a transition between the New Expense screen and Expense Picture screen.
  8. Click on the dot in the middle of the transition to edit it.
  9. Under Event, click on "None" and select "On Create".
  10. Click on Property Mapping and connect "New Expense" and "Expense" by holding the left click of the mouse on New Expense towards Expense.

We can now build the UI of the screen.

  1. Double-click to open the Expense Picture Screen. Add a "Header" brick from the Marketplace and customize it as follows:
    • 1st tab: Enable "Hide Button" toggle; Title = "Capture Receipt"
    • 2nd tab: X = Left, Y = Top, Height = 90, Width = 100%
    • 4th tab: Title property from context editor = "Expense Picture", Hide Button = true by enabling the toggle
  2. Add a "Button" brick from the Marketplace:
    • 1st tab: Text = "Take Picture"
    • 2nd tab: X = Center, Y = Bottom
  3. Add a "Camera" brick from the Marketplace:
    • 2nd tab: X = Center
  4. Go back to the Expense Picture screen and click on Take Picture Button, go to 4th tab and click on the f(x) button for "On Click" Interaction.
    • Add "Dispatch Event" and select the Event constant by clicking on the "New Camera"'s "Take Screenshot (UI Event)"
    • Drag & drop from the Prop picker "Expense Picture" and select "Expense (Expense)".
    • Drag & drop from the Prop picker "New Camera" and select "Screenshot (File)".
    • Drag & drop a "Persist Object" brick from the Marketplace.
    • Drag & drop "Set Expense's attributes" from the Marketplace.
    • Drag & drop a "Dispatch Event" from the Marketplace.
    • Link these components as shown below.

button_onClick

Finally, since we want to go back to the Home screen we need to add a transition in the app's screen flow editor.

  1. Go back to Expense App (Screen Flow Editor).
  2. Create a transition between Expense Picture screen and Home Screen and select event "On Picture Taken" by clicking on the trasition's dot.

5.5 Expense Details Screen

So we have covered most of our application: we can create new expenses, attach receipts to them, and view the list of expenses created. The final step is to be able to view the details of an expense when we click on it.

We can therefore now go back to the Home Screen and configure the "View" button to trigger an event when clicked, and record which expense is being viewed.

In the Context Editor of the Home Screen:

  1. Add an "Event" and name it "On View Expense".
  2. Add a "Property", name it "Selected Expense" and set its type to "Expense".
  3. Go to "Visual Editor" tab and open the list item renderer (by clicking on Edit on the list).
  4. Select the "View Button" button and on the 4th tab, configure its "On Click" interaction by clicking on the f(x) button next to it:
    • Under Prop Picker, drag&drop Item Renderer, select "Current Item (Object)" property. Click on "Get Value".
    • Under Prop Picker, drag&drop Home Screen, select "Selected Expense (Expense)" property. Click on "Set Value".
    • Connect "Get UI Property" value output to "Set UI Property" value input.
    • Connect Action Control flow output to "Set UI Property" Control Flow input.
    • Add "Dispatch Event" brick from the Marketplace. Set Event to Home screen's "On View Expense".
    • Link the control flow from the "Set UI property" to the control flow of "Dispatch Event".
    • Close the action.

We now build a new screen to view the details of an expense, the Expense Details screen. This screen is displayed when clicking on one of the "View" buttons in Home screen. It contains:

  • A header
  • A label to display the description
  • A label to display the amount
  • A label to display the currency
  • A picture to display the receipt picture.

View Expense Screen

Like we did between the New Expense screen and the Expense Picture screen, we need to provide the Expense Details screen with the expense that we clicked on in the Home screen.

  1. Add a new Screen, name it Expense Details and open it.
    • Click on tab "Spec & Doc".
    • Add a "Property", name it "Expense" and set its type to Expense.
  2. Go back to Expense App (Screen Flow Editor).
    • Create a transition between Home Screen and Expense Details Screen.
    • Click on the transition's dot and set the event to "On View Expense" and under Property mapping, map the property "Selected Expense" to "Expense".

Let's now build the UI.

  1. Open Expense Details Screen.
  2. Add a "Header" UI Component from the Marketplace and configure it as follows:
    • 2nd tab: X = Left, Y = Top, Height = 90, Width = 100%
    • 1st tab: Title property from context editor = A function that retrieves the expense's Description from the screen's Expense property (use Get Expense's attributes from the Marketplace)

And finally we allow the user to go back to the Home screen.

  1. Go back to Expense App (Screen Flow Editor).
  2. Create a transition between Expense Details Screen and Home Screen. Click on the dot, create a new event (+ Button), click on Header and select "On Back (UI Event)".