# Show and edit derived attributes on invoices

Surface workflow-derived fields on invoice detail (static or LLM), optionally allow edits, show LLM reason on hover, and map values into Twinfield or Exact Online narrative fields.

Use **Set derived attribute** not only for approval routing: also put a clear, business-ready field on the **invoice detail** view. Turn on **Show on invoice detail** so reviewers see it above the line items, and optionally **Allow editing on invoice detail** so they can fine-tune the value (for example a posting description) before **Send to Twinfield** or Exact Online export.

This is one of the clearest ways Cortena shows **workflow flexibility**: you decide the key, how the value is built, whether humans can override it, and how accounting export consumes it, without hard-coding a new product field for every ERP note.

**Who this is for:** Finance admins configuring invoice workflows, and AP reviewers who need an extra note or description on the invoice before it is posted to **Twinfield**, **Exact Online**, or similar systems that accept free-text descriptions.

For using derived attributes as **approval matrix** columns (for example business line), including **Static value** vs **LLM derived**, see [Set derived attributes](https://help.cortena.ai/guides/workflows/set-derived-attributes). This article focuses on **invoice display**, **editing**, and **accounting descriptions**.

## 1. Why this matters for accounting systems

Many ledgers do not only store amounts and GL accounts. They also accept **additional narrative** on the purchase entry: a short description, note, or free-text header that appears in the journal, supplier ledger, or bank matching screens.

| System | Typical narrative field | How Cortena can fill it |
| --- | --- | --- |
| **Twinfield** | Purchase total-line **description** (and optional free-text headers when the daybook allows) | Build a derived attribute (e.g. `description`), show/edit it on the invoice, then map it on **Export to accounting** via field expressions such as `${derived.description}` |
| **Exact Online** | Purchase entry header **Description** | Same pattern: store the text as a derived attribute, optionally let reviewers edit it, map **header description** on the Exact export step |

Common business needs:

- Prefix every posting with `Invoice ${invoice_number}` so Twinfield or Exact always show a searchable reference
- Combine supplier + PO (`${invoice_supplier_name} / ${purchase_order_number}`) for cost controllers who live in the GL, not in Cortena
- Let a reviewer add a short cost-centre comment or project code *after* extraction, without changing the PDF
- Keep the **same** text the reviewer saw on invoice detail as what is sent on export (no silent rewrite at send time)

## 2. Configure the workflow step

1. Open **Settings → Workflow** for the tenant.
2. From **ADD STEP → Actions**, add **Set derived attribute** (or select an existing one on the canvas).
3. Give it a clear **Label**. This is what operators see in the workflow strip (example: **Set invoice header description**).
4. Set **Attribute key**: lowercase letters, digits, and underscores; must start with a letter (example: `description`).
5. Set how the value is produced:
   - **Value source → Static value**: plain text and/or tokens (click a variable chip), for example `Invoice ${invoice_number}`.
   - **Value source → LLM derived**: write an **Instruction for the LLM**; Cortena uses the invoice and booking match. Configure **When the LLM returns nothing or fails** if you need an **Empty / error** path (full detail in [Set derived attributes](https://help.cortena.ai/guides/workflows/set-derived-attributes)).
6. Under display options:
   - Tick **Show on invoice detail**. The field appears above line items once the step has written a value (or when editing is allowed).
   - Tick **Allow editing on invoice detail**. Reviewers can change the value with spreadsheet-style editing on the invoice. When editing is allowed, the field is always shown.
7. **Save** / publish the workflow so new invoices pick up the change.

![Workflow: Set derived attribute with show and edit options](https://help.cortena.ai/assets/img/help/show-edit-derived-attributes/01-set-derived-attribute-workflow.png)

**Screenshot:** Workflow canvas with **Set invoice header description**, attribute key `description`, value `Invoice ${invoice_number}`, and both **Show on invoice detail** and **Allow editing on invoice detail** enabled.

### Useful value tokens

| Token | Meaning |
| --- | --- |
| `${invoice_number}` | Supplier invoice number |
| `${purchase_order_number}` | PO on the invoice |
| `${invoice_supplier_name}` | Supplier name |
| `${invoice_recipient_company}` | Recipient company |
| `${invoice_recipient_name}` | Recipient name |
| `${currency}` | Currency code |
| `${note}` | Invoice note |
| `${service_period}` | Service period(s) |
| `${derived.<key>}` | Another derived attribute set earlier |

If the resolved value would be empty, the set step fails. Prefer tokens that exist on your invoices, or combine with plain text.

## 3. What reviewers see on the invoice

After the workflow step runs, open the invoice. Fields you marked to show appear in the header area **above the line items**, with a humanized label (key `description` → label **DESCRIPTION**).

![Invoice detail: editable Description derived attribute](https://help.cortena.ai/assets/img/help/show-edit-derived-attributes/02-derived-attribute-invoice-detail.png)

**Screenshot:** Invoice **BC-0002** with an editable **DESCRIPTION** field showing `Invoice BC-0002`, ready before **Send to Twinfield**.

Behaviour:

- **Show only**: value is visible; not editable from the invoice (still changeable only by another workflow set step).
- **Allow editing**: click the field (or use spreadsheet-style keyboard navigation like other header fields), change the text, press **Enter** to save. **Escape** cancels. Blur / Tab / click outside commits the pending value.
- **LLM reason**: if the value was set by **LLM derived**, hover the field to see the model's short reason (why that value was chosen).
- Edits are stored on the invoice as that derived attribute key, so later export mapping reads the **same** value the reviewer saw.

## 4. End-to-end example: Twinfield / Exact header description

**Goal:** Every purchase export should carry a short description such as `Invoice BC-0002`, visible in Cortena and editable if the AP team needs a different wording for the ledger.

### Step A: Derive and surface the text

1. Add **Set derived attribute** early enough that it runs before export (often after matching / before approval or immediately before **Export to accounting**).
2. Key: `description`
3. Value: `Invoice ${invoice_number}`
4. Enable **Show on invoice detail** and **Allow editing on invoice detail**.

### Step B: Map it on Export to accounting

On the **Export to accounting** node for your target:

- **Twinfield**: map the total-line / description field expression to `${derived.description}` (or the slot your tenant uses for purchase narrative).
- **Exact Online**: map **header description** to `${derived.description}` so the Exact purchase entry **Description** is filled only when you intentionally set it (Cortena does not invent a default invoice-number description).

### Step C: Review before send

1. Open an invoice that has passed the set step.
2. Confirm **DESCRIPTION** (or your label) shows the expected text.
3. Edit if needed, e.g. `Invoice BC-0002 · Q1 license`.
4. Click **Send to Twinfield** (or your Exact export action). The exported narrative should match what is on the invoice.

**Workflow flexibility:** The same **Set derived attribute** building block also powers approval-matrix columns, later **Conditional** branches on derived values, and export field expressions. Showing and editing on the invoice is how you keep humans in control of ERP-facing free text without forking the product for each accounting system.

## 5. Patterns beyond description

You can run several set steps with different keys:

| Pattern | Example key | Show / edit | Typical use |
| --- | --- | --- | --- |
| Posting description | `description` | Show + edit | Twinfield / Exact narrative |
| Business line (routing) | `business_line` | Often hidden, or show-only | Approval matrix column: see [Set derived attributes](https://help.cortena.ai/guides/workflows/set-derived-attributes) |
| Channel / segment | `channel` | Show-only | Visibility for reviewers; branch later |
| Combined reference | `export_note` | Show + edit | Custom string for Sheets / Drive templates |

Prefer **one clear key** per purpose. Overwriting the same key later in the workflow replaces the previous value.

## 6. Tips and limitations

- **Editing implies show**: when **Allow editing** is on, the field is always shown on invoice detail.
- **Publish the workflow**: display flags come from the **published** workflow definition for the tenant.
- **Only editable keys can be patched**: the API only accepts edits for keys marked editable in that workflow; other keys are rejected.
- **Synced / locked invoices** follow the same edit locks as other header fields. Once exported and locked, values are not meant for casual change.
- **Character limits in the ERP** still apply (for example Twinfield total-line description length). Keep values short if the target system truncates.
- **Exact Online**: header description is sent only when mapped; it is not auto-filled from the invoice number.
- **Permissions**: configuring the node needs workflow management; editing on the invoice needs normal invoice edit access for that tenant.

## Quick reference

| Task | Where |
| --- | --- |
| Add / configure **Set derived attribute** | **Settings → Workflow** → **ADD STEP → Actions** |
| Show field above line items | Node panel → **Show on invoice detail** |
| Allow spreadsheet-style edits | Node panel → **Allow editing on invoice detail** |
| See or edit the value | Invoice detail: header area above line items |
| Send text to Twinfield / Exact | **Export to accounting** → field expression `${derived.<key>}` |
| Use the same attribute for approvers | [Set derived attributes](https://help.cortena.ai/guides/workflows/set-derived-attributes) |
