In this video, we will create the Order entity and screens for order management.
We will also modify the Customers editor to display the list of orders.
2.1 Name Pattern Concept
First, we will create a readable instance representation for the Customer entity.
It is a template for a string representing a record, corresponding to an entity.
This string will be used in UI components like a table cell or a dropdown list.
In order to do this, expand "Data Model" node in the project tree and open "Customer" entity's text.
Open entity editor and click on "Edit" button to edit instance name.
Select "name" attribute in the attributes list. The NamePattern annotation will be generated
2.2 Adding Entity to Master-Details Relation
We have our customers set and ready, now we need orders.
In the data model, the Order should have a many-to-one relationship to the Customer as displayed.
In the Data Model section of the CUBA project tree, right-click on this node and select New > Entity.
Enter the Entity name − Order.
The entity will have the following attributes: Date, its type is date, and this attribute is mandatory.
Another field for the order - its amount that represents a total sum of money that should be paid for this order.
The data type for amount property is BigDecimal and this attribute is also mandatory.
Now let's create the many-to-one relationship between the Order and the Customer.
In order to do this, we create the 'customer' attribute.
- Enter the name of the attribute in the name field.
- Select Association in the attribute type field.
- After that, select the Customer entity which is being referenced, in the type field.
- Set the cardinality to many-to-one.
- At this step, we can define, how exactly we want to choose a customer when creating an order.
- In our project, it will be a dropdown list with a lookup action and the ability to open the selected customers in a new window.
Since the new entity includes the 'customer' reference attribute, we have to create an entity view that includes this attribute.
2.3 CUBA Views
Views mechanism is the platform feature that should be explained separately.
Most of the visual components in CUBA UI are data-aware, and display data that is fetched from the database.
So, when we define a view, we specify what exactly should be extracted from the database to the UI.
There are three predefined types of views.
Let's just assume that for the "Order" entity, its name consists of "date" and "customer" fields.
The first is the _minimal view, it includes only the fields, required to display the Instance Name of an entity.
In this case for the Order entity, it will obviously contain the "date" and "customer" fields.
The _local view includes all non-reference fields.
So, for the Order, it will contain both date and amount fields.
The _base view contains all local fields and the field used for the instance name.
For the Order entity all fields will be extracted.
To create a view, right-click on Order entity in the data model section of the navigation tree and click New → View.
- The view designer will be opened.
- Enter order-with-customer as the name of the new view.
- Check the customer attribute in the list of attributes below and select the _minimal view for the customer
Click OK to save the new view.
2.4 Updating Database and Creating Screens for Details Entity
Since we have created a new entity, the database needs to be upgraded.
- First, generate scripts according to our new data model.
- And then - update database using CUBA→ Update database menu.
Now let’s create the standard screens for the Order.
- Select the entity and invoke New → Screen.
- Select order-with-customer as the view for both browser and editor, and click Create.
Let’s see how the created screens look in the running application.
Run the application by selecting 'CUBA → Start application server' and make sure the screens are functional by entering some data.
Open the Orders browser screen and create a new order on behalf of the existent customer.
2.5 CUBA Data Components Concept
Now we will make the Customer editor display the list of orders.
But before that we need to explain data components in CUBA in more details.
Data components are non-visual elements of screens that provide data loading and they utilize CUBA views for that purpose.
Those components bind data to data-aware visual components and facilitate data saving.
There are the following categories of data components:
- Containers - provide the thin layer between entities and data-aware visual components.
Different types of containers can hold either single instances or collections of entities.
- Loaders - load data from the middle tier to containers.
- DataContext - tracks changes in loaded entity instances and saves changed back to the middle tier upon request.
Therefore to add the orders list grid to the editor we need to do the following:
- Add data container that can hold a collection of orders and bind a grid to it.
- Load data for a customer
- Load orders data that belongs to the selected customer only.It means that before loading data into the grid we need to instruct data loader to filter data.
2.6 Displaying Master - Detail Data in the UI
Let's do it.
- Open customer editor screen XML descriptor, switch to Designer tab.
- Click on customer data container and assign ID to a customer data loader - we will need it later.
- Then in the components palette find Collection in the Data components group.
- Drag this component to the data section in screen components hierarchy panel.
- Select this component and switch to its property palette.
- Set the class com.company.sales.entity.Order to "class" property and create data loader ID.
- You can use _local view for this data container.
- In the bottom of the properties palette you will see the query that loads data to this container.
- Add filtering condition with a parameter as shown.
select o from sales_Order o where o.customer = :customer
Now we need to add a grid and bind it to orders data container.
- In the components palette find Table and drag it to components hierarchy below email field as shown.
- To bind it to data container, open component properties tab and select orders data container.
- The table columns will correspond to the attributes of the Order entity displayed in the table.
- Let's make the screen a bit more useful and add a label for this table.
- Right-click on the table and select Wrap Into → Group Box.
- Select generated group box and set its label property to "Orders".
- Also, we can increase the table width a bit by setting its "width" property to 100% to fill the group box.
Final step - select orders that belong to a selected customer only.
To do this, we need to update Java controller for the customer editor screen.
- Switch to the "Text" tab and click to a controller definition marker.
- The controller's source is empty now, so what should we do?
- First - we need to disable automatic data load for the screen, because we need custom data load process.
- To disable automatic data load, remove LoadDataBeforeShow annotation from the class.
- Next step - load customer data.
- In this version CUBA generates event objects based on what is happening on the screen.
- For our case we need to redefine data loading before show.
- Let's subscribe to this event.
- Press Alt+Insert in the controller's source code and select "Subscribe to Event".
- Find "BeforeShowEvent" in the list and press "OK".
- Studio will generate an empty method.
- In this method we'll implement data loading for customer and its orders.
- To control data loading, we need an access to data loaders defined in screen descriptor.
- To do this, you need to add references for those components to the controller's code.
- Press Alt+Insert and select Inject... in the menu.
- Select customer and orders data loaders and customer data container from the components list.
Done!
- Now we can implement custom data loading in the generated method.
- Write code to invoke customer data loading method.
- Then set parameter value for the orders data loader.
- Entities are stored in data container, so we get customer entity from it and load data to order data loader.
- Let's do it in the code.
protected void onBeforeShow(BeforeShowEvent event) {
customerDl.load();
ordersDl.setParameter("customer", customerDc.getItem());
ordersDl.load();
}
Now we're ready to start the application.
To do this, we need to restart the application server.
Let's see how the customer editor looks in the running application now.
Open the Customer editor.
As you can see, the table of Orders contains the order we created a few moments ago.
In this video we have added Orders to our application and implemented a master-detail form.
In the next video, we will make our application more complex by adding two more entities: Order Line and Product
Also we will implement business logic for Order default values substitution and automatic order amount calculation.