# Track a User's Progress in a Custom Exercise

Track a user’s progress through a custom exercise by using the [`sfdc_enablement` Apex namespace](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_namespace_sfdc_enablement.htm) classes and [`LearningItemType` metadata type](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_learningitemtype.htm.htm).

To implement an evaluation of a user's progress in a custom exercise, extend the `sfdc_enablement.LearningItemEvaluationHandler` abstract Apex class. Add the Apex class name to the `apexEvaluationHandler` field of the `LearningItemType` metadata record.

To calculate the user’s progress through an exercise as a percentage and return the progress status, use the `sfdc_enablement.LearningEvaluationResult` class inside the `sfdc_enablement.LearningItemEvaluationHandler`. By default, the [evaluateLearningItem wire adapter](https://developer.salesforce.com/docs/platform/lwc/guide/reference-evaluate-learning-item.md) in the Salesforce Lightning Design System checks whether this `apexEvaluationHandler` class is specified for the custom exercise.

To retrieve details of the learning item record and pass it as input to `sfdc_enablement.LearningEvaluationResult`, use the `sfdc_enablement.LearningEvaluation` class.

The `sfdc_enablement.LearningItemProgressStatus` enum provides the progress status, which can be `NotStarted`, `InProgress`, or `Completed`. In this example, we set:

- `NotStarted` to be equal to 0.00%
- `InProgress` to be greater than 0.00% and less than 100.00%
- `Completed` to be equal to 100.00%

:::note
`LearningEvaluationResult.learningItemProgress` expects a double, so only the first 2 decimal values are considered. For example, 0.001 is rounded to 0.00 and 99.999 is rounded to 100.00.
:::

## Example

Here’s an example of a custom progress evaluation for the screen flow exercise. See [Create a Custom Screen Flow Exercise](/docs/sales/enablement/guide/enablement-custom-exercise-with-screen-flows.md).

To get the files shown in this example, download [enablement_custom_exercise_screen_flow.zip](https://resources.docs.salesforce.com/rel1/doc/en-us/static/misc/enablement_custom_exercise_screen_flow.zip).

This code shows an example of the Apex implementation. You can find this code in the `ScreenFlowEvaluationHandler.cls` file.

```js
global class ScreenFlowEvaluationHandler extends sfdc_enablement.LearningItemEvaluationHandler {
    /**
     * Example code that tracks the screen flow completion by
     * checking the number of screens that the user has navigated.
     */
    global override sfdc_enablement.LearningEvaluationResult evaluate(sfdc_enablement.LearningEvaluation learningEvaluation) {
        sfdc_enablement.LearningEvaluationResult result = new sfdc_enablement.LearningEvaluationResult();
        Double percentage = 100.0d;

        Map<String, Object> details = learningEvaluation.getDetails();

        String currentScreen = (String) details.get('currentScreen');

        String allScreensString = (String) details.get('allScreens');
        List<String> allScreens = allScreensString.split(',');

        String status = (String) details.get('status');
        if (status == 'FINISHED') {
            percentage = 100;
        } else {
            Integer index = 0;
            for (Integer i = 0; i < allScreens.size(); i++) {
                if (allScreens.get(i).equals(currentScreen)) {
                    index = i + 1;
                    break;
                }
            }

            if (index == allScreens.size()) {
                percentage = 99.0d;
            } else {
                percentage = (Double.valueOf(index) / Double.valueOf(allScreens.size())) * 100.0d;
            }
        }

        result.setLearningItemProgress(percentage);

        if (percentage == 100.0d) {
            result.setLearningItemProgressStatus(sfdc_enablement.LearningItemProgressStatus.Completed);
        } else if (percentage == 0.0d) {
            result.setLearningItemProgressStatus(sfdc_enablement.LearningItemProgressStatus.NotStarted);
        } else {
            result.setLearningItemProgressStatus(sfdc_enablement.LearningItemProgressStatus.InProgress);
        }

        return result;
    }
}
```

Here’s code showing an example of the `LearningItemType` metadata record that includes the `apexEvaluationHandler` field. This field references the `ScreenFlowEvaluationHandler` Apex class. You can find this code in the `ScreenFlowLearningItemType.learningItemType` file.

```xml
<LearningItemType xmlns="http://soap.sforce.com/2006/04/metadata">
    <apexEvaluationHandler>ScreenFlowEvaluationHandler</apexEvaluationHandler>
    <apexSerializerDeserializer>ScreenFlowSerializerDeserializer</apexSerializerDeserializer>
    <customField>ScreenFlow_Field__c</customField>
    <customObject>ScreenFlow_Object__c</customObject>
    <developerName>ScreenFlowLearningItemType</developerName>
    <icon>standard:flow</icon>
    <lightningComponentDefinition>screenFlowViewer</lightningComponentDefinition>
    <masterLabel>Screen Flow Learning Item Type</masterLabel>
</LearningItemType>
```
