# `Codat.Accounting.Invoices`
[🔗](https://github.com/iamkanishka/codat.git/blob/v1.0.0/lib/codat/accounting/invoices.ex#L1)

Read and write accounting invoices (sales invoices / accounts receivable).

## Supported Operations

| Operation          | Description                                    |
|--------------------|------------------------------------------------|
| `list/2,3`         | Paginated list of invoices                     |
| `get/3,4`          | Single invoice by ID                           |
| `create/4,5`       | Create a new invoice (async)                   |
| `update/5,6`       | Update an existing invoice (async)             |
| `delete/3,4`       | Delete an invoice (async, not all integrations)|
| `get_create_model` | Get required fields for create                 |
| `get_update_model` | Get required fields for update                 |
| `stream/2,3`       | Lazy stream of all invoices                    |
| `fetch_all/2,3`    | All invoices as a list (concurrent paging)     |
| `get_attachments`  | List attachments for an invoice                |
| `upload_attachment`| Upload a PDF/image attachment                  |

## Example

    # List open invoices
    {:ok, page} = Codat.Accounting.Invoices.list(client, "company-id",
      query: "status=Open",
      order_by: "-issueDate"
    )

    # Stream all invoices without loading all into memory
    Codat.Accounting.Invoices.stream(client, "company-id")
    |> Stream.filter(&(&1["amountDue"] > 0))
    |> Enum.take(10)

    # Create an invoice (async)
    {:ok, push_op} = Codat.Accounting.Invoices.create(
      client, "company-id", "connection-id",
      %{
        issueDate: "2024-01-15",
        dueDate: "2024-02-15",
        customerRef: %{id: "customer-id"},
        lineItems: [%{description: "Consulting", quantity: 1, unitAmount: 1000}]
      }
    )
    # Poll or await webhook for completion
    {:ok, done} = Codat.Platform.PushOperations.poll_until_done(
      client, "company-id", push_op["pushOperationKey"]
    )

# `create`

```elixir
@spec create(
  Codat.Client.t() | String.t(),
  String.t(),
  String.t() | map(),
  map() | keyword()
) ::
  {:ok, map()} | {:error, Codat.Error.t()}
```

Creates a new invoices (async). Returns a push operation.

# `delete`

```elixir
@spec delete(Codat.Client.t() | String.t(), String.t(), String.t() | keyword()) ::
  {:ok, nil} | {:error, Codat.Error.t()}
```

Deletes a invoices by ID (async).

# `download_attachment`

```elixir
@spec download_attachment(
  Codat.Client.t() | String.t(),
  String.t(),
  String.t(),
  String.t() | keyword()
) :: {:ok, binary() | map() | list() | nil} | {:error, Codat.Error.t()}
```

Downloads a specific attachment for an invoice.

# `fetch_all`

```elixir
@spec fetch_all(Codat.Client.t() | String.t(), String.t() | keyword(), keyword()) ::
  {:ok, [map()]} | {:error, Codat.Error.t()}
```

Fetches all invoices across all pages concurrently.

# `get`

```elixir
@spec get(Codat.Client.t() | String.t(), String.t(), String.t() | keyword()) ::
  {:ok, map()} | {:error, Codat.Error.t()}
```

Fetches a single invoices by ID.

# `get_attachments`

```elixir
@spec get_attachments(
  Codat.Client.t() | String.t(),
  String.t(),
  String.t() | keyword()
) ::
  {:ok, map()} | {:error, Codat.Error.t()}
```

Lists attachments for an invoice.

## Example

    {:ok, attachments} = Codat.Accounting.Invoices.get_attachments(
      client, "company-id", "invoice-id"
    )

# `get_create_model`

```elixir
@spec get_create_model(Codat.Client.t() | String.t(), String.t(), keyword()) ::
  {:ok, map()} | {:error, Codat.Error.t()}
```

Returns the push model for creating invoices.

# `get_update_model`

```elixir
@spec get_update_model(
  Codat.Client.t() | String.t(),
  String.t(),
  String.t() | keyword(),
  keyword()
) ::
  {:ok, map()} | {:error, Codat.Error.t()}
```

Returns the push model for updating a invoices record.

# `list`

```elixir
@spec list(Codat.Client.t() | String.t(), String.t() | keyword(), keyword()) ::
  {:ok, Codat.Pagination.t()} | {:error, Codat.Error.t()}
```

Returns a paginated list of invoices.

# `stream`

```elixir
@spec stream(Codat.Client.t() | String.t(), String.t() | keyword(), keyword()) ::
  Enumerable.t()
```

Returns a lazy `Stream` of all results.

# `update`

```elixir
@spec update(
  Codat.Client.t() | String.t(),
  String.t(),
  String.t(),
  String.t() | map(),
  map() | keyword()
) :: {:ok, map()} | {:error, Codat.Error.t()}
```

Updates an existing invoices (async).

---

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