Skip to main content
Skip table of contents

Getting Started - Create a Case File

Introduction

In this guide, a case file is created.
This serves as a binding between Data Sources, Reports or Aggregations and their results.

Workflow as a real-world example

To explain this concept a bit more "plastic ", we could describe the workflow as follows:

  • As a customer of a company using Data Intelligence, I would like to conclude a contract for payment by installments.

    • I prepare my bank statements or account information at home and take them with me to the store where I want to conclude the installment contract.

      • SYNCHRONIZE DATA SOURCES after importing the account(s) in Access (via WF2.0)

    • The seller now wants to check my data, so he takes a folder, writes my name on it, and puts the account information I brought along as a copy. He then staples the originals to my customer account.

      • CREATE CASE

    • Depending on the amount I want to finance, he has to do different things on the basis of the data, such as a risk assessment, an income statement, etc. So he writes the required evaluations on a note, which he also puts in the folder.

      • ADD REPORT TO CASE

    • Now he passes the folder on to the finance department, which looks at the documents and creates the requested evaluations.

      • CREATE REPORT (happens in the background, as if I can not see what is happening in the office of the store)

    • The financing department now comes back to the seller, gives him the folder with the evaluations in it, and he can evaluate whether I can close the contract.

      • GET REPORT(s)

    • If he needs further evaluations due to the results (e.g. whether I play), he can add the additionally required evaluations to the folder and hand them over again to the financing department, which creates an additional evaluation.

      • ADD MORE REPORTS TO CASE

  • One month later, I want to finance something else. But this time the amount is much smaller.

    • The seller therefore only copies my account information of my salary account and attaches this to a new folder for the financing. The whole process now starts over again but uses my already known account information again.

      • CREATE NEW CASE (with existing data sources)

    • However, as the data is unfortunately no longer up to date, he asks me to update my account details for the account and bring new bank statements with me.

      • SYNCHRONIZE DATA SOURCE again after updating the account in Access (via WF2.0)

Prerequisites

TL:TR

Used Systems

See Environments page for detailed information.

Used Endpoints

To create a report, at least the following endpoints are required:

Description

HTTP Method

Process Controller Endpoint

Link to API Doc

Create a case

POST

/api/v1/cases

finAPI API Documentation

cURL Example

Step 1 - Create a case (cURL)

A case requires one or more data sources. This allows the reports to know which accounts should be used.

It can also restrict the time period with maxDaysForCase or datePeriodForCase elements.

The withTransactions element can be used here to define the default behavior of the reports transaction output later.

Request to create a case with maxDaysForCase:

BASH
curl --location 'https://di-sandbox.finapi.io/api/v1/cases' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--data '{
  "dataSourceIds": [
    "4e760145-2e65-4242-ac33-488943528c93"
  ],
  "maxDaysForCase": 89,
  "withTransactions": true
}'

Request to create a case with datePeriodForCase:

BASH
curl --location 'https://di-sandbox.finapi.io/api/v1/cases' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <access_token>' \
--data '{
  "dataSourceIds": [
    "4e760145-2e65-4242-ac33-488943528c93"
  ],
  "datePeriodForCase": {
    "dateFrom": "2023-01-01",
    "dateTo": "2023-02-01"
  },
  "withTransactions": true
}'

The response for maxDaysForCase looks like this:

JSON
{
  "id": "0b5d1980-63ec-4f3c-bbcf-dd81b044d580",
  "maxDaysForCase": 89,
  "creationDate": "2023-02-01 00:00:00.000",
  "dataSources": [
    {
      "id": "4e760145-2e65-4242-ac33-488943528c93",
      "creationDate": "2020-01-01 00:00:00.000"
    }
  ]
}

Implementation Guide

See a full working project here: finAPI Data Intelligence Product Platform Examples (Bitbucket)
Code from this guide can be found here: finAPI Cases Creation (Bitbucket), finAPI Reports (Bitbucket)
Environment overview can be found here: Environments

The guidelines and the example project are written in Kotlin with Spring Boot. But it is easily adoptable for other languages and frameworks.
For the HTTP connection, we are using here plain Java HttpClient, to be not restrictive for the client selection and that everything is transparent.

Only the actual functionality is discussed in this guideline. Used helper classes or the models can be looked up in the source code.

However, we always recommend using a generated client from our API, which reduces the effort of creating models and functions to access the endpoints and eliminates potential sources of error.

To learn how to generate and apply the API client using the Process Controller "Create user and exchange with access_token" as an example, please see the Getting Started - Code Generator (SDK) Integration.

Please also note that the code presented here and also the repository is only an illustration of a possible implementation. Therefore, the code is kept very simple and should not be used 1:1 in a production environment.

Step 1 - Create a case

Creating a case is the next step after creating a Data Source. First, we create a class called CaseService.
It requires the Data Intelligence URL, and our DiProcessesRepository, as well as the mandatory ObjectMapper.

We create a body for the case. We give it a list of the dataSourceIds, we’ve created and returned previously.
The dataSourceIds can also consist of accountId if a data source contains unwanted accounts. Internally, the system also resolves the data source to accounts.

If several data sources exist (e.g. a cash account and a joint account at different banks), all data source IDs can be specified.
All accounts will then be taken into consideration in the report.

The response is validated again. However, a possible exception is caught here in order to be able to store a clean error status (CASE_CREATION_FAILED) in the system. This can be very relevant in support cases.
Afterward, the original exception is thrown again.

If everything was ok, we update the status to CASE_CREATED and return the result, that we have access to the caseId in the caller function.

We need a createPostRequest() method here, which prepares the client request.
This could also be solved centrally, but here we use the methods in each class to make it a bit more understandable.

KOTLIN
@Service
class CaseService(
    @Value("\${finapi.instances.dataintelligence.url}") private val diUrl: String,
    private val diProcessesRepository: DiProcessesRepository,
    private val objectMapper: ObjectMapper
) {

    /**
     * Create a case.
     */
    @Throws(RuntimeException::class)
    fun createCaseFile(
        accessToken: String,
        dataSourceIds: List<String>,
        processEntity: DiProcessEntity
    ): CaseResponseModel {
        log.info("[${processEntity.processId}] Starting create a case...")
        val client = HttpClient.newBuilder().build()

        // create body for the case
        val body = CaseRequestModel(
            dataSourceIds = dataSourceIds,
            withTransactions = true
        )

        // send request
        val response = client.send(
            // create request URI for https://<data_intelligence>/api/v1/cases
            createPostRequest(
                accessToken = accessToken,
                endpointUri = URI_CASES,
                body = objectMapper.writeValueAsString(body)
            ),
            HttpResponse.BodyHandlers.ofString()
        )

        // check for status code is 2xx or log and throw an exception
        try {
            StatusCodeCheckUtils.checkStatusCodeAndLogErrorMessage(
                response = response,
                errorMessage = "Unable to create case."
            )
        } catch (ex: RuntimeException) {
            processEntity.status = EnumProcessStatus.CASE_CREATION_FAILED
            diProcessesRepository.save(processEntity)
            throw ex
        }

        // map the result
        val caseResponse = objectMapper.readValue(response.body(), CaseResponseModel::class.java)

        // save successful state for case creation
        processEntity.status = EnumProcessStatus.CASE_CREATED
        diProcessesRepository.save(processEntity)

        log.info("[${processEntity.processId}] Finished create a case...")
        return caseResponse
    }

    /**
     * Create a POST HttpRequest.
     */
    private fun createPostRequest(
        accessToken: String,
        endpointUri: String,
        body: String
    ): HttpRequest {
        return HttpRequest.newBuilder()
            // build URL for https://<data_intelligence><endpointUri>
            .uri(URI.create("${diUrl}${endpointUri}"))
            // set Content-Type header to application/json
            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .header(HttpHeaders.AUTHORIZATION, "Bearer $accessToken")
            // add the body
            .POST(
                // use empty body to sync all accounts
                HttpRequest.BodyPublishers.ofString(body)
            ).build()
    }

    companion object {
        private val log = KotlinLogging.logger { }
        const val URI_CASES = "/cases"
    }
}

Now we have finished the function that can create the case.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.