In this video we will make our application a bit more complex and realistic by adding order lines and products.

Also we will implement an additional application logic for the order amount recalculation.

3.1 Adding More Entities, Composition Relationship

Let's modify the data model.

Now order will contain a set of order lines, which refer to a product. And order amount will be calculated based on the quantity and price of the products in the order.

The order contains a collection of OrderLines which implies that they have a one-to-many relationship.

The type of the relationship is Composition.

This is a kind of one-to-many relation, that means that the OrderLines are created and edited alongside the original order.

The OrderLine, in turn, refers to the Product as many-to-one. The type of this relationship is Association.

Let's create the Product and define its attributes: 'name' which is a String and 'price' which is a BigDecimal.

Both attributes are mandatory.

Set name as the Instance name of the entity.

Now let's create the OrderLine entity.

Add the following mandatory attributes:

  • 'order' which is a many-to-one reference to the Order;
  • 'product' which is a many-to-one reference to the Product, let's set a dropdown lookup type for it.
  • finally, the 'quantity' which is a BigDecimal attribute that sets the product quantity for a given order line.

Now let's define a collection of lines for the order.

Open the Order entity for editing and create the 'lines' attribute which is a Composition reference to the OrderLine entity.

The corresponding attribute on the reverse side of the relationship will be automatically inserted in the "Mapped By" field.

Now we can generate the database update scripts and apply them to the database in the same way as we did before. Please note, that you may need to stop application server in order to update the database.

The next step - creating the user interface.

3.2 Creating Views and UI for New Entities

To begin with, we need to prepare the views for loading proper entities to display them in the application.

For a starter, OrderLine will always be used with product name and price, so let's create the orderLine-with-product view and add the product attribute to it. Specify the _local view for the associated "product" attribute.

The order editor should display a collection of order lines, so let's define the order-edit view for the Order entity. Specify the _minimal view for the Customer entity.

After that select "lines" attribute and use "order-line-with-product" view for it.

Now order lines data is fetched with an order instance and we don'd need to load them separately as we did in customer editor from the previous video because we defined a view that will load this data.

All we need to do - is change a view for the order data container and replace it with order-edit view. This view will fetch "lines" along with the order instance.

Open an order editor and change a corresponding property value for the data container.

Now let's create the browsers and editors for the new entities.

First, let's do this for the Product entity.

Both browser and editor will be similar to screens we have created for other entities like Customer.

Menu path is the same: Right-Click on the Product entity → New → Screen → Browser And Editor.

After that, let's create the user interface for Order Lines.

The list of order lines will be displayed in the Order editor, so we don't need a browser for order lines.

Therefore, we will create only an editor for order lines. While creating the screen, select order-line-with-product as a view.

Start the application server and enter a couple of products for testing purposes.

After that we can open order editor.

As you can see, the order editor does not contain order lines.

Let's move on to the next part of the project and add order lines browser with editing functionality to the order editor.

3.3 Displaying Details Records in the Editor Screen

Now we need to add a table to the order editor and display order lines data in it.

Despite on the view update we need a "collection" data container that will be used by a UI table component. Let's add it to order editor screen.

  • Open order editor screen descriptor and find "Collection" data component in the palette.
  • Drag and drop it on the orderDc data container.

By doing this, we create a nested data container for order lines.

  • Select this data container and specify "lines" as its property field value.
  • Then assign an ID - linesDC - for this container.

We have a data container, now we need a UI component.

  • Find the "Table" component in the palette and drag it to the "column" container under the "customer" field.
  • Specify the container for the component.
  • Assign an ID - linesTable - for the table.

As you see, there is only one column - quantity - is displayed. Let's add product name and price to the UI.

  • Open the columns editor and add the following columns manually: product.name and product.price. The direct order line attributes, such as product and quantity, can be selected from a dropdown list, while the related entity attributes should be specified manually. Also we reorder columns to make a better user experience.
  • Set table width to four hundred pixels and height to two hundred pixels to make UI a bit nicer.

All the attributes used in the columns will be loaded from the database when the screen is opened, as defined the order-edit view.

If the application server is running, perform hot deploy, by right-clicking on editor tab and selecting "deploy file to tomcat".

You we will be able to view the changes simply by switching to the web browser and reopening the order editor.

3.4 Adding Editing Functionality to the UI

Now we need to add a functionality for editing order lines.

To do this let's add standard "Create", "Edit" and "Remove" buttons to the editor.

  • First, we need to define edit actions for the table. Select the table in the UI designer, select properties palette and invoke actions editor.
  • Add three actions - Create, Edit and Remove. Specify proper ID and Type for each action.
  • Actions are created - now we need to add buttons to the user interface.
  • In the components palette select buttons panel component, drag and drop it on the table component.
  • After that, add three buttons to this panel using drag and drop.
  • Assign an action and ID for each button by specifying it in button's properties palette. You can use autogeneration feature to generate button IDs.

Let's update the order using updated editor. Reopen order editor screen and add a couple of order lines to the order.

The final phase - implement the order amount calculations based on the product price and quantity. It will be a sum of product prices multiplied by product quantity for all order lines.

  • Open the Order editor screen controller.
  • Let’s inject the link to the linesDc data container into the controller. We will use it to get information about order lines.
  • Press Alt+Insert in the source code and select "Inject" → LinesDc.
  • We need to subscribe to changes that happen in this container's collection to recalculate order amount.
  • To do this, press "Alt+Insert" again and select "Subscribe to event" → "Data container events" → "Collection Change Event" for lines data container.
  • Now let's write a method that recalculates and updates order amount and invoke it from the event handler.
  • Create "calculateOrderAmount" method that returns BigDecimal value. The first step in calculation algorithm is set initial value of the amount to zero. Then loop through all order lines and sum price of a product multiplied to its quantity.
  • To assign amount value to a current order we get its instance by calling getEditedEntity method.
  • Assign the result of the method to "amount" property of the order being edited.
protected void calculateAmount() {
    BigDecimal amount = BigDecimal.ZERO;
    for (OrderLine line : linesDc.getItems()) {
        amount = amount.add(line.getProduct().getPrice().multiply(line.getQuantity()));
    }
    getEditedEntity().setAmount(amount);
}

The job is almost done.

One tiny thing we need to do to avoid excessive recalculations - we need to recalculate order only when order lines are changed.

Therefore "refresh" event type for the collection should not start recalculation. Let's modify our handler.

protected void onOrderLinesDcCollectionChange(CollectionContainer.CollectionChangeEvent<OrderLine> event) {
    if (event.getChangeType() != CollectionChangeType.REFRESH) {
        calculateAmount();
    }
}

Finally, make amount field in the order editor not editable to avoid conflicts with manual changes.

Redeploy file to tomcat and update the order by adding order line or changing product amount to see changes in order sum.

Now we have completed the main goal of our quick start tutorial. Join our community, take a look at Sampler and consult the documentation on our website. Thank you for watching!