 Perfect. So hi everyone. I'm Pablo and the Android app lead developer. I'm here to tell you about the rule engine and how to use it with the SDK. First of all, I want to introduce to you a little overview of what the program rules are and how they are used in the DHH So the program rules is a way to evaluate the current state of data entry form and respond to that state with a series of actions and effects. So just a little picture here to let you see the whole thing. So we back from that context for example an enrollment which has its own enrollment date, enrollment organization unit, the enrollment has a status that can be active, completed and it has a series of events with values that the user is in the data entry can be an event or the enrollment form and these events have their own event date, data values, organization unit, category combinations and based on these sets of data the program rules can be evaluated and they can respond with a series of effects can be assigning a value to a variable, hiding a field, so in a warning and many more they're all in the DHH2 documentation. The main part of the program rules is the expression is where everything is evaluated. The program rule expression is the way to evaluate this context and it gets a series of variable that conforms an expression which has to be evaluated to true or false. It can use as I said some variables that are linked to mostly to data elements or attributes. It can use special functions and as I said they have to be evaluated to true or false. So how does this work in Android? So to evaluate the program rules we use the rule engine. This is a Java library which has developed by the UIO and you have the repository link in this presentation so you will be able to have a look at it. So I want to remind that the rule engine as for now is not part of the SDK it's its own library. It has its own Java classes so we need to translate some of these classes from the SDK to the rule engine models and then rule actions and effects have to be carried out by the developer. So the rule engine is going to by the way the program rules and tell you what to do but it's up to the developer to apply those rules to their fields, to whatever fields you have created. The rule engine uses the Antler expression evaluation parser which is also a library from the UIO and this expression parser takes care of the rule engine expression of the rule engine expressions and evaluates it to true or false. This is also shared between Android and backend not web. Web has its own implementation so we can be mostly sure that if something works in Android it's also going to work on for the backend. The rule engine needs to step initialization when you're using it in the in an Android application. First you have the metadata configuration that creates or that is used to build what is called rule engine context. The rule engine context that data that is not going to change to the data in the real data entry. Then the second step would be adding the contextual data for the rule engine that would mean is what do you want to evaluate with this context? Do you want to evaluate the for example an enrollment? Do you want to evaluate a single event or you want to evaluate everything within this context? The rule engine context setup is as you can see very simple. You need to provide a list of program variables. These variables are linked to attributes, data element for an event and you have several different cases. Then you have to provide the list of rules you want to evaluate. This usually will be linked to either a program or a program stage. Then you will have to add some what is called supplementary data. This would be for example the user roles, some of the unit's codes that the rule engine would need to be able to evaluate some of these functions that you can use in the expressions. Then finally you will have also to provide any constant value that is available in the metadata. For example, if in web the number P is configured then you have to pass that in this list. With this you have the rule engine context. What you can do with the rule engine context is building the rule engine. This is the second step. You just would need to call the two engine builder and then build and you can pass to one of these two other objects. For example, if you would want to evaluate program rules within an environment, you will need to add it to the rule engine, like enrollment and passing the enrollment. Also, you will have to add all the events within that enrollment so the rule engine knows what's going on. If you are in a program without registration, a single event program, you won't pass the enrollment but you will pass all of the events from that program. Finally, with the rule engine object already set up, you can use it to evaluate with a context using one of these functions. There are a lot of evaluate functions available. The most common freeway would be .evaluate, which will evaluate everything within the rule engine context. You can pass it the current enrollment. This is done like this because as you add new data to the enrollment form, you would need to be updating this enrollment object and the same with the event. There are also several other evaluate functions that will let you pass a set of program rules. I just want to evaluate this program rule and nothing else. It's also there for you to use. The three main uses would be these ones. How do we connect the SDK to the rule engine? This is a library, so the SDK knows nothing about the rule engine. The SDK has already its own variables for models that the rule engine uses. For example, in the SDK, we have the program rule variable, the program rule, enrollment and event that you have already seen. The rule engine has its own model implementation for rule variable, rule event, and rule environment. We need in the Android app a translation class or a mapping class. For example, in the SDK, we have the program rule variable, which has a property called program rule variable source time. This would be have to be taken account in the mapping to transform this model into one of those from the rule engine that would be rule variable attribute, rule variable calculated value, rule variable current event, and there are several others. This has to be done in the Android app. What happens once we have the rule engine and we ask them to evaluate? What we receive from the rule engine is a list of rule effects. Each of these rule effects has a rule action object. There are 30 different types. They are rule action height field, a rule action assign, rule action height section, rule action show error, and many more. Each of them have its own variables, like saying which field you have to target and what do you have to do with that. And then the rule effect, it has also a stream, a data stream, which for some cases is the result of an evaluated expression that you need to display as a static test. Just like an example, the rule action height field has this property content, which is a message you have to show the user when a field is going to be hidden. And then it also has the property field, which is the UID of the element or attribute you need to hide. So when we receive this effect, what we have to do is go to our list of field, find this field with that UID and remove it from the list. And then maybe, I don't know, so we now pop up to the user with the message that the action required. This is all well-documented in the rule engine documentation and in DHH2 docs. Something to take into account when working with the rule engine is that we have to clear data when it is hidden. So this is something like the way we work with the rule engine in the Android app is that when it's time the user has data in the form, it is stored locally in the SDK database. So when we get a height field effect, if we don't clear that value, we don't remove that value from the SDK and we think that value is going to go to the server. And we don't want that because a program rule already said that value shouldn't exist. Next thing you have to know is that program rules configuration can have issues like if a program rule hasn't been completely fully configured in web, it can be downloaded to the Android app with the SDK and it may provoke some failures when triggered. These are really difficult to debug, so you have to take that into account. For example, when you use the mapping classes to pass from SDK models to rule engine model. Also, you have to be careful with possible loops when something changes in the form, in the data. You should be run in a next iteration of the rule engine. And if you have program rules that assign and then hide the same value, you can be stuck in a loop. So you have to have something in mind to avoid this. And then the last thing, which I have already said at the beginning, although the rule engine expression evaluation is set between Android and backend, the web has a different implementation. When you configure in the program rules expressions from 235, there is a check that it's using the same expression evaluator like Android and backend, so that would be a way to know if everything is okay. But for previous versions of DSA2 and having the program rules run, web has its own implementation. So you may see some difference here and there that we are trying to mitigate as much as we can. It's something that could happen. Here, just to end this presentation, I prepared a list of links to the DSA2 Android app, so you can check how the rule engine is implemented. I think you have everything you would need in order to implement the rule engine to whatever app you want to build. So you have access to how the rule engine context is built for an enrollment, how the evaluation is performed during the enrollment, and then the last two Kotlin classes. You could use it very straightforward. They are how we apply the rule express to a list of fields and this mapping class to parts from SDK models to rule engine models. So these classes you could just copy the code and you would be okay to use them, but they are in Kotlin. That would be, thank you very much. He has no exercise, so any questions you have? This is the moment. No question. Thank you, Pablo. Let's continue with the next session. This is also about some utility classes and services and helpers that are around the development of the Android application. What I'm talking about services, I mean some logic and services helpers or engines like the rule engine that are around the SDK that helps with the logic that is related to DSA2. For example, in the previous day we have seen how to create new events, how to create values, how to create targeted instances, but it is true that there is a DSA2 logic that has to be taken into account to allow the users to do some things. For example, if a targeted instance is already enrolled in a program, that CI cannot be enrolled again in the same program while that CI has an active enrollment, think like that. Or if the event is not repeatable, users should not allow the user to create a new event. So for that we have some services like the event service that provides some helpful methods like to check if an event is repeatable or not. So what do we have to check? If we do it on our own, what do we have to check? Okay, so to determine if an event can be evasive or not, first of all you have to verify if the user has that right access to the program. Also if the enrollment link to that event is active, because if the enrollment is completed, the event cannot be modified. If the registration unit also has opening and closing dates and if the event date is within that train, also if the user has access to the attribute option combo linked to the event, which means that the user has to have access to all the category options linked to that attribute option combo. And also finally, in case the category options have start and end dates, you have to check if the event date falls within that train. So as you can see there is a lot of things to think into account when you want to know if an event can be edited or not. So this method encapsulates all this logic and just gives you a result. Okay, this event can be edited or this event cannot be edited and the reason is that one. Okay, the enrollment service, for example, to check if a user can access or edit an enrollment and it will depend on the access level of the program, open protective flows. Also the data access of the user to the program also depending on the access level of the program, you have to check the registration unit if the registration unit is in the capture scope or in the search scope. So yeah, so all these things you need to take into account to know if a user can edit or access an enrollment and also we have helpers for that. And the period helper, for example, this helper includes handy methods to get the date in a period. For example, the month has 30 or 31 days or 28. Also to get a period or period ID based on a period type and a date to get this unique identifier with a syntax that expects it to. And also to get a period value ID or get all the periods available for this data set, taking into account the future periods of the data set. Also, there is a geometry helper because I think you're starting on a version 230 or 232 the geometry model change. And now it includes point polygon or multi polygon. The geometry object becomes more complex. So this helper helps with this object, for example, to validate if the future type is polygon, okay, these coordinates are valid for a polygon or if it's off type point, these coordinates are actually a point. So yeah, the helper helps you to validate the geometry object to extract the points, polygons or polygons or multi polygons and also create new value geometry object. And finally, the relationship helper that yeah, starting on version 230. The relationship model changed a lot. Previously, you can only have relationships between a TI and a TI. Now you can have a relationship between a TI enrollment or event to a TI enrollment or event. So yeah, the object is more complex. And this helper helps you with all that logic. Yep. Thanks. Any question about this? The services we are not doing any exercise about this is just for you to know that those services are there for you to use them. And yeah, that we have all the things to deal with the logic. One question please. Yeah. Do we have the kind of service for aggregates? Can you repeat? We have said this for aggregated parts. I think that you only show service for well. Yeah, for the aggregated part, well, the period helper helps a lot in the aggregated part because when you want to list, for example, the periods available for a particular data set, depending on the period type of the data set, the period helper helps with that. And also, yeah, we have the validation rule engine that we saw yesterday and also the data set indicator engine that we are not going to see in this workshop, but it's also there. Yeah, but that's all. Some other things that are coming in the next version, for example, is a value type helper that helps in the validation of the value type, for example, if it's integrated positive or it's a date or, I don't know, a coordinate, it helps you to validate the values. Okay, welcome. Any other questions? This is about the program indicator engine. This is also this is another engine that we have in the SDK and this engine takes care of the evaluation of the program indicator, but only in the context of a single TI and usually or an event and usually for the data entry form. I mean that this program indicator engine is intended to be used to evaluate those indicators that are shown in the data entry screen. If you think you have in mind the web form, there is a box showing a list of program indicators during the data entry form. So this engine is for that, is to evaluate the indicators shown in the data entry form. So far, it's not possible to evaluate program indicators across all the target entity instances, but it's something that is coming. And also a good thing about this engine is that it uses the this third parser that we have talked about in previous sessions and also that Pablo mentioned for the rule engine is the common grammar that is served by the backend and by Android. So you would expect to have the same result both in Android and in the backend when it comes to the parsing of the expression. The program indicator engine is very easy to use. It is located in the program model, the program indicator engine, and it has two methods. And the first is to evaluate a program indicator in the context of an event and this is used for an event without registration. And the second one is for enrollment. And these are the indicators that are shown in the target capture app in web. Indicators that are evaluated in the context of our whole enrollment. Okay, so let's do an exercise about this. Okay, so welcome to this session about analytics. So here we are going to see a new feature that was introduced in the SDK in the last version in 1.4. And it is an initial model with some basic analytics features. So the purpose of this model is to be able to have some kind of analytic values based on the values stored on the device. I mean that this model will evaluate program indicators or indicators, but always based on the data stored in the device. So it does not take the values in the server, just the values that are present in the device. This is important. Maybe in future versions we can combine data coming from the server on the device, but currently the current scope is just to analyze data in the device. The similar functionality tries to be similar to the analytic endpoint in the web API. So maybe you are familiar with that endpoint. So you can have kind of an event line list or in tabular form. So far in version 1.4 and what we have introduced is the event line list analytic. So this kind of analytic gives you usually a list of events with evaluated values like for example a prime indicator for that particular event or the data element inside that. So you can print in a list the event in a table or you can build a graph like this to see the evolution. For example, in the context of a TI you can see the evolution of a particular prime indicator across all the events. So it's very similar if you are familiar with web, very similar to the event report line list functionality. So you can have all the events in the line with the prime indicators that you want and the data elements that you want. And the main use case I would say that is to print information about repeatable stages so you can see the evolution of some values. And this is a capture of the Android capture app and screenshot. Yeah and yeah these values are evaluated using the analytic model in this decay. But the representation in a graph is the responsibility of the application. Well the event line list analytic repository is quite easy to use. It has a mandatory property just one that is the promise state. So you have to to define the promise state that you want to evaluate. So it's the only mandatory property. Additionally you can specify the promise the target entity instance. For example if you want to display the evolution of a value in the context of a target entity instance you can filter by target entity instance. And then you can add the data element and the prime indicator that you want. And the syntax is the same that for any other repository this builder pattern with data element. If you add more than one data element or more than one prime indicator they are concatenated. So in this case you will have both data element one and data element two in the response. And the prime indicator. Okay so that's all for this initial yeah analytic model that we have in the decay.