# Using logical statements (JsonLogic)

In manifest [JsonLogic](http://jsonlogic.com/) is used for visibility and disabled conditions, for figuring out next screen user needs to be taken and in request data transformers.

```typescript
interface JsonLogic {
  type: "jsonlogic";
  schema: JsonLogic;
}
```

JsonLogic can access variables ([more info](http://jsonlogic.com/operations.html#var)). The following namespaces are available:

## Available Namespaces

| Namespace          | Description                                                       | Example                                 |
| ------------------ | ----------------------------------------------------------------- | --------------------------------------- |
| `input.*`          | User input fields                                                 | `{"var": "input.data.field"}`           |
| `input.first_name` | Hardcoded fields (no data. prefix)                                | `{"var": "input.first_name"}`           |
| `flags.*`          | Framework flags                                                   | `{"var": "flags.editing"}`              |
| `quote.*`          | Quote response data                                               | `{"var": "quote.gross_payment_amount"}` |
| `policy.*`         | Policy response data                                              | `{"var": "policy.publicId"}`            |
| `claim.*`          | Claim response data (FNOL)                                        | `{"var": "claim.id"}`                   |
| `lead.*`           | Lead data                                                         | `{"var": "lead.email"}`                 |
| `item.*`           | Item/product data                                                 | `{"var": "item.id"}`                    |
| `dataset.*`        | Dataset items (see [dataset namespace](#dataset-namespace) below) | `{"var": "dataset.data.company.name"}`  |
| `asset.*`          | Asset URLs                                                        | `{"var": "asset.logo"}`                 |
| `document.*`       | Document data                                                     | `{"var": "document.lead.offer.url"}`    |
| `route.*`          | Current route/screen                                              | `{"var": "route.path"}`                 |
| `query_string.*`   | URL query parameters                                              | `{"var": "query_string.ref"}`           |
| `context.*`        | Repeater context                                                  | `{"var": "context.repeater_index"}`     |
| `form.*`           | Form state                                                        | `{"var": "form.has_errors"}`            |
| `active_policy.*`  | Active policy in FNOL                                             | `{"var": "active_policy.id"}`           |
| `renewal.*`        | Policy renewal data                                               | `{"var": "renewal.id"}`                 |

**Important**: `flags` is a top-level namespace, NOT under `input`.

* Correct: `{"var": "flags.editing"}`
* Wrong: `{"var": "input.flags.editing"}`

For a complete list of available flags, see the [visibility condition guide](https://docs.kasko.io/kasko-frontend-documentation/core-concepts/visibility-condition).

## Dataset Namespace

The `dataset` namespace provides access to loaded dataset items. Dataset items are loaded when a field with the `in_dataset` validation rule has a value.

### Structure

```
dataset.{field_name}.{property}
```

* `{field_name}` - The form field name that holds the dataset item ID (e.g., `data.company`, `data.location`)
* `{property}` - Any property from the dataset item

### Dataset Item Properties

Every loaded dataset item has:

* `id` - The dataset item ID (e.g., `dai_abc123...`)
* `dataset_id` - The dataset ID (e.g., `dat_xyz789...`)
* Plus any custom fields defined in the dataset

### Examples

```json
// Access a dataset field
{"var": "dataset.data.company.name"}

// Access nested properties
{"var": "dataset.data.company.address.city"}

// Check if dataset is loaded
{"!!": [{"var": "dataset.data.company"}]}

// Compare dataset values
{"===": [{"var": "dataset.data.company.country"}, "DE"]}

// Use in visibility condition
{
  "visibility_condition": {
    "type": "jsonlogic",
    "schema": {
      "===": [{"var": "dataset.data.company.type"}, "enterprise"]
    }
  }
}
```

### With Repeaters

For repeater fields, include the index in the path:

```json
// Access dataset for first agent's location
{"var": "dataset.data.agents.0.location.city"}

// Dynamic access using cat operator
{"var": {"cat": ["dataset.data.agents.", {"var": "context.repeater_index"}, ".location.city"]}}
```

## Custom operators

### `iso_date`

It takes in `Date` object and returns ISO String of it. If value passed in is not `Date` object, there will be a warning message and output will be untouched value that was passed in.

This is useful when input has Date object, but some operations have to be made with this value using JsonLogic (e.g. `substr` to get year, month, day etc.).

| Logic                            | Date                   | Result         |
| -------------------------------- | ---------------------- | -------------- |
| `{ "iso_date": {"var":"date"} }` | `{ date: new Date() }` | `"2019-06-11"` |

This operator can also accept modifier value as a second (optional) parameter, that is a string.

| Logic                                                                  | Date                   | Result         |
| ---------------------------------------------------------------------- | ---------------------- | -------------- |
| `{ "iso_date": [{"var":"date"}, "-5 days"}`                            | `{ date: new Date() }` | `"2019-06-06"` |
| `{ "iso_date": [{"var":"date"}, "+1 month"}`                           | `{ date: new Date() }` | `"2019-07-11"` |
| `{ "iso_date": [{ "iso_date": [{"var":"date"}, "+2 years"}, "-1 day"}` | `{ date: new Date() }` | `"2021-06-10"` |

### `length`

Returns length of array.

| Logic                                     | Input                          | Result |
| ----------------------------------------- | ------------------------------ | ------ |
| `{ "length": { "var": "input.numbers" }}` | `{ numbers: ['a', 'b', 'c'] }` | `3`    |

### `to_object`

Builds object from flat entries list.

| Logic                                 | Input | Result                 |
| ------------------------------------- | ----- | ---------------------- |
| `{"to_object": ["foo", 1, "bar", 2]}` | ...   | `{"foo": 1, "bar": 2}` |

### `path`

Has ability to access context from string.

Let's say you have repeater component and in there you must have ability to show/hide field with jsonlogic based on value on particular field in repeater array. We can use `path` operator in combination with `var` to do so.

With data:

```json
{
  "agents": [
    {
      "name": "John"
    },
    {
      "name": "Jane"
    },
    {
      "name": "Alfred"
    }
  ]
}
```

| Logic                                               | Context                 | Result            |
| --------------------------------------------------- | ----------------------- | ----------------- |
| `{"path": "agents.{repeater_index}.name"}`          | `{ repeater_index: 2 }` | `"agents.2.name"` |
| `{"var": {"path": "agents.{repeater_index}.name"}}` | `{ repeater_index: 2 }` | `"Alfred"`        |
