# `ExReconcile.Result`
[🔗](https://github.com/ARTARNA/ex_reconcile/blob/v0.1.0/lib/ex_reconcile/result.ex#L1)

The structured output of `ExReconcile.reconcile/3`.

## Fields

- `:matched` - list of `{left, right}` pairs that were successfully reconciled with no
  field differences outside configured tolerances.
- `:discrepancies` - list of `{left, right, [field_diff]}` tuples where the pair was
  matched (same key) but one or more fields differ beyond tolerance. Each `field_diff` is
  a map describing the field and the delta; see `t:field_diff/0`.
- `:unmatched_left` - transactions from the left list with no counterpart in the right.
- `:unmatched_right` - transactions from the right list with no counterpart in the left.

## `field_diff` shape

```elixir
# Amount discrepancy
%{field: :amount, left: 1050, right: 1000, delta: -50}

# Date discrepancy
%{field: :date, left: ~D[2024-01-15], right: ~D[2024-01-16], delta: 1}

# Description discrepancy
%{field: :description, left: "Coffee Shop", right: "COFFESHOP LTD"}
```

# `discrepancy`

```elixir
@type discrepancy() ::
  {ExReconcile.Transaction.t(), ExReconcile.Transaction.t(), [field_diff()]}
```

# `field_diff`

```elixir
@type field_diff() ::
  %{field: :amount, left: number(), right: number(), delta: number()}
  | %{field: :date, left: Date.t(), right: Date.t(), delta: integer()}
  | %{field: :description, left: String.t(), right: String.t()}
```

# `pair`

```elixir
@type pair() :: {ExReconcile.Transaction.t(), ExReconcile.Transaction.t()}
```

# `t`

```elixir
@type t() :: %ExReconcile.Result{
  discrepancies: [discrepancy()],
  matched: [pair()],
  unmatched_left: [ExReconcile.Transaction.t()],
  unmatched_right: [ExReconcile.Transaction.t()]
}
```

# `clean?`

```elixir
@spec clean?(t()) :: boolean()
```

Returns `true` when the reconciliation is clean: no discrepancies and no unmatched
transactions on either side.

## Examples

    iex> ExReconcile.Result.clean?(%ExReconcile.Result{})
    true

    iex> ExReconcile.Result.clean?(%ExReconcile.Result{unmatched_left: [%ExReconcile.Transaction{amount: 1}]})
    false

# `summary`

```elixir
@spec summary(t()) :: map()
```

Returns a summary map with counts for each category.

## Examples

    iex> result = %ExReconcile.Result{matched: [{"a", "b"}], unmatched_left: ["c"]}
    iex> ExReconcile.Result.summary(result)
    %{matched: 1, discrepancies: 0, unmatched_left: 1, unmatched_right: 0, total_left: 2, total_right: 1}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
