Up and running fast with Mendix (Part 3)

Where we left off in Part 2: we had the base functionality for taking orders. But our fledgling burger business is not going to last long if we aren’t ringing up customers for the right amount.

Calculating the total cost of the order

In most cases, you want to do the calculation on the Event’s of a entity (create, commit, delete, rollback). This saves the performance hit of using a calculated attribute which gets its value on the fly, when it’s retrieved for display.

However, for our purpose here, we’re going to take the easy route and use a calculated field.

Create a new microflow in the Orders module called MC_OrderTotal. Add a parameter for Order in the same way we did for the earlier microflow.

Add an action to the flow and set it’s type to Create a Variable.

A settings box will pop up for the action where you can specify the Data type (set it to Decimal), give a default value (set it to zero), and name the variable (name it Total):

Now we need to do a calculation on multiple items. That means we will need to first retrieve them with a retrieve action, and then loop through the items and run up the total (insert cash register ka-ching! sound effect here).

Retrieve Action

What to retrieve? Well, we’re going to need the items associated with the orders, which means two retrievals.

For the first, select the OrderLine->Order association to get at the OrderLine:

Find the Association under the OrderParam variable

Next, add a loop:

We will iterate over the OrderLineList, retrieve the Item associated with each, and add it’s price * the OrderLine quantity to the Total.

Now add a Retrieve Action inside of the Loop area:

Now add a Change Variable Activity and provide it with the folowing formula:

I don’t know if it’s necessary, but it’s good to put a Continue node following the Change Variable Activity.

Your Microflow should now look like this:

Lastly, we need to return the Total that we calculated.

To return a value, double click on the red Microflow endpoint and fill out the fields:

Type: Decimal, Return value: $Total

Making a calculated value field

We’re going to make use of the calculation by editing the TotalCost field of the Order entity.

In the Orders Domain Model, double-click on the TotalCost field and choose Calculated in the Value area of the properties:

Next, select our MC_OrderTotal Microflow:

Now the field will indicate to you that it is a calculated value and not a stored one:

This means that the database will never have the value stored, it will always produce the value when the UI requires it.

Note: the advantages to a calculated field is that it simplifies logic requirements where a field is only needed for display and not for tracking. However, in almost all cases, it is better to have a stored value.

With the entity field wired to the Microflow, you will notice there is now at least one error in your project; the Modeler will complain that it can’t use a calculated value as a search field:

The value proposition of a calculated field is rapidly diminishing.

We’ll just delete it from the search filters.

Add the calculated value to the Data Grid as a column:

Data source: attribute Orders.Order.TotalCost

Run it:

Everyone’s favorite status

Data constraints

After your first few orders, the buzz of getting paid for sub-standard cuisine will fade and your low-paid employee (yourself) is getting confused by the number of orders on the screen. So the manager (also yourself) asked if you could show only orders that are not paid.

It’s easy. Just double click on the Data Grid which shows the orders (on the title part of the control), and go to the Data source tab. You will see the option to add a constraint:

In the pop-up, choose Status, Equals, and Not Paid:

Everyone’s least favorite status.

This is all you need to do to constrain the visible orders to Not Paid only.

Let’s help the manager (yourself) even more by making the grid default sort on the time of order creation.

Go back to the Domain Model of orders and double click on your Order entity. In the properties, check the createdDate option:

This field, along with changedDate, owner, changedBy, are all available via the Mendix platform as opposed to adding manually. They are always available to select here, you simply have to tell Mendix you want to track them.

Back on the Orders Overview page, double-click on the Sort order of the data grid which appears under the action bar:

Add the following:

And run it:

A Better Total Cost

Our subtotal field is easy enough to use, but we want to store the total in the database because, as you know, prices may vary.

For record keeping, we want to capture the data from the associated data that may be subject to change.

We can make the field better with a simple change the field to a stored field and rework the logic slightly.

The event we are interested in is the creation of an OrderLine. When this happens, we want to recalculate the total cost and refresh the UI. So the OrderLine creation will cause the Order to update.

Modify the Total Cost Microflow

Back in our MC_TotalCost, we want to change the incoming parameter type to OrderLine.

We are now handling an incoming OrderLine

Now we need to retrieve the Order that the incoming OrderLine is associated with:

Now, we get all the OrderLines associated to this order, which will include the one we passed in to the Microflow:

Make sure that the loop iterator is aligned to the OrderLineList we just made an Action for.

After the loop, change the Order with the summarized value:

Set the Refresh in client option to Yes

Overall, the Microflow should now look like this:

Back in the Orders Domain Model, double click one OrderLine entity, and add an Event handler for After/Commit that calls our MC_OrderTotal.

The tiny lightning bolt indicates our excitement!

Okay, now let’s put it to use by showing a Subtotal on the New Order page:

Find Textbox under the widget

Provide the following settings for the textbox: Attribute = Orders.Order.TotalCost, Editable=Never, and give it “Subtotal” as a caption.

Run it:

A burger shy of the American Ideal