# Building Tran Codes

In this tutorial, we will learn how to manage transaction codes using the GraphQL API.


Source: https://www.twisp.com/docs/tutorials/building-tran-codes

Transaction codes play a critical role in identifying and categorizing transactions in the ledger, and designing them is an important part of using Twisp. By following the steps outlined in this tutorial, you will be able to create and manage transaction codes in your own ledger.

> **Task:**
>
> - Create a new tran code using the `createTranCode` mutation
> - Update fields on an existing tran code using the `updateTranCode` mutation
> - Get data about a tran code with the `tranCode` query
> - Delete (lock) a tran code using the `deleteTranCode` mutation

---

## Prerequisites

Before you start, you should have added accounts to your ledger. See the tutorial on [Setting Up Accounts](/docs/tutorials/setting-up-accounts).

## Getting started

The easiest way to interact with the Twisp GraphQL API is to login to the **Twisp Console** and use the **GraphiQL** tool.

If you prefer to use your own GraphQL client, you can send authenticated requests to the Twisp API endpoint.

To seed your setup with some example accounts, sets, and tran codes, you can use the [Example Setup](/docs/tutorials/example-setup).

## Create a new tran code

To create a new tran code, use the `createTranCode` mutation. The `input` argument specifies the full configuration of the tran code and how transactions posted with this code will be structured, including all entries written to the ledger.

Many of the fields in the `TranCodeInput` object (and its nested objects) allow for CEL expressions to be used, which will be evaluated during the `postTransaction` call and the results will be used in the creation of a transaction posted with the new transaction code.

Note that the `params` field allows for the specification of parameters that can be used in CEL expressions for the transaction and entries fields. These parameters can be used to make the transaction code more flexible and dynamic, allowing for the creation of more complex transactions.

The `transaction` and `entries` fields, respectively, act as templates for the [Transaction](/docs/reference/graphql/types/object#transaction) and [Entries](/docs/reference/graphql/types/object#entry) that are created when this tran code is used in a `postTransaction` call.

Here's an example of creating a new tran code for a `BOOK_TRANSFER`:

**Request**

```graphql
mutation CreateTranCode(
  $tcBookTransferId: UUID!
  $journalGLIdExp: Expression!
) {
  createTranCode(
    input: {
      tranCodeId: $tcBookTransferId
      code: "BOOK_TRANSFER"
      description: "Book transfer between two internal accounts."
      metadata: { category: "Internal" }
      params: [
        { name: "crAccount", type: UUID, description: "Account to credit." }
        { name: "drAccount", type: UUID, description: "Account to debit." }
        {
          name: "amount"
          type: DECIMAL
          description: "Amount with decimal, e.g. `1.23`."
        }
        {
          name: "currency"
          type: STRING
          description: "Currency used for transaction."
        }
        {
          name: "effective"
          type: DATE
          description: "Effective date for transaction."
        }
      ]
      vars: { amount2: "decimal('1.00')", amount3: "this.amount2" }
      transaction: {
        journalId: $journalGLIdExp
        effective: "params.effective"
        description: "'Book transfer for $' + string(params.amount)"
      }
      entries: [
        {
          accountId: "params.drAccount"
          units: "params.amount"
          currency: "params.currency"
          entryType: "'BOOK_TRANSFER_DR'"
          direction: "DEBIT"
          layer: "SETTLED"
        }
        {
          accountId: "params.crAccount"
          units: "params.amount"
          currency: "params.currency"
          entryType: "'BOOK_TRANSFER_CR'"
          direction: "CREDIT"
          layer: "SETTLED"
        }
      ]
    }
  ) {
    tranCodeId
  }
}
```
**Response**

```json
{
  "data": {
    "createTranCode": { "tranCodeId": "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855" }
  }
}
```
**Variables**

```json
{
  "journalGLIdExp": "uuid('822cb59f-ce51-4837-8391-2af3b7a5fc51')",
  "tcBookTransferId": "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855"
}
```

Once created, transactions can be posted using this transaction code by providing the required fields in a `TransactionInput` object. The inputs for a `postTransaction` using this tran code must include fields for the `crAccount`, `drAccount`, `amount`, `currency`, and `effective`.

> **Note:**
>
> Designing tran codes is one of the most important parts of using Twisp, and it can take some time to familiarize yourself with the process.
>
> Read more about tran codes on the [Encoded Transactions](/docs/accounting-core/encoded-transactions) page.

## Query tran codes

The `tranCode` query can be used to read back an existing tran code using its `tranCodeId`.

Here is an example query:

**Request**

```graphql
query GetBookTransferTranCode {
  tranCode(id: "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855") {
    code
    description
    params {
      name
      type
      description
    }
    transaction {
      journalId
      effective
      correlationId
      description
    }
    entries {
      accountId
      layer
      direction
      units
      currency
    }
    status
    metadata
  }
}
```
**Response**

```json
{
  "data": {
    "tranCode": {
      "code": "BOOK_TRANSFER",
      "description": "Book transfer between two internal accounts.",
      "params": [
        {
          "name": "crAccount",
          "type": "UUID",
          "description": "Account to credit."
        },
        {
          "name": "drAccount",
          "type": "UUID",
          "description": "Account to debit."
        },
        {
          "name": "amount",
          "type": "DECIMAL",
          "description": "Amount with decimal, e.g. `1.23`."
        },
        {
          "name": "currency",
          "type": "STRING",
          "description": "Currency used for transaction."
        },
        {
          "name": "effective",
          "type": "DATE",
          "description": "Effective date for transaction."
        }
      ],
      "transaction": {
        "journalId": "uuid('822cb59f-ce51-4837-8391-2af3b7a5fc51')",
        "effective": "params.effective",
        "correlationId": "''",
        "description": "'Book transfer for $' + string(params.amount)"
      },
      "entries": [
        {
          "accountId": "params.drAccount",
          "layer": "SETTLED",
          "direction": "DEBIT",
          "units": "params.amount",
          "currency": "params.currency"
        },
        {
          "accountId": "params.crAccount",
          "layer": "SETTLED",
          "direction": "CREDIT",
          "units": "params.amount",
          "currency": "params.currency"
        }
      ],
      "status": "ACTIVE",
      "metadata": { "category": "Internal" }
    }
  }
}
```

This query will respond with the fields for the `BOOK_TRANSFER` tran code created above, identified by its UUID.

The `params` field in the response includes information about the parameters required by this transaction code, such as the name, type, and description of each parameter.

The `transaction` field in the response includes details about the transaction that is created when this transaction code is used.

The `entries` field in the response includes information about the entries that are created when this transaction code is used.

Finally, the response includes the status of the transaction code, which can be either `ACTIVE` or `LOCKED`, and any metadata associated with the transaction code.

## Modify an existing tran code

To modify an existing tran code, use the `updateTranCode` mutation.

Provide the tran code's `id` and the fields to update in the `TranCodeUpdateInput` input object. You can only modify a subset of fields for data integrity purposes.

Here's an example of modifying the description of an existing tran code:

**Request**

```graphql
mutation UpdateTranCode($tcBookTransferId: UUID!) {
  updateTranCode(
    id: $tcBookTransferId
    input: {
      description: "Book transfer between two customer wallet accounts."
      vars: { hello: "string('world')" }
      entries: [
        {
          accountId: "params.drAccount"
          units: "params.amount"
          currency: "params.currency"
          entryType: "'BOOK_TRANSFER_DR'"
          direction: "DEBIT"
          layer: "SETTLED"
          metadata: "{'first': 1}"
        }
        {
          accountId: "params.crAccount"
          units: "params.amount"
          currency: "params.currency"
          entryType: "'BOOK_TRANSFER_CR'"
          direction: "CREDIT"
          layer: "SETTLED"
          metadata: "{'second':2}"
        }
      ]
    }
  ) {
    tranCodeId
    description
    entries {
      metadata
    }
    vars
    history(first: 2) {
      nodes {
        version
        description
        vars
      }
    }
  }
}
```
**Response**

```json
{
  "data": {
    "updateTranCode": {
      "tranCodeId": "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855",
      "description": "Book transfer between two customer wallet accounts.",
      "entries": [
        {
          "metadata": "{'first': 1}"
        },
        {
          "metadata": "{'second':2}"
        }
      ],
      "vars": {
        "amount2": "decimal('1.00')",
        "amount3": "this.amount2",
        "hello": "string('world')"
      },
      "history": {
        "nodes": [
          {
            "version": 2,
            "description": "Book transfer between two customer wallet accounts.",
            "vars": {
              "amount2": "decimal('1.00')",
              "amount3": "this.amount2",
              "hello": "string('world')"
            }
          },
          {
            "version": 1,
            "description": "Book transfer between two internal accounts.",
            "vars": {
              "amount2": "decimal('1.00')",
              "amount3": "this.amount2"
            }
          }
        ]
      }
    }
  }
}
```
**Variables**

```json
{
  "tcBookTransferId": "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855"
}
```

This operation updates the description of a transaction code. The response includes the UUID and the updated description of the transaction code, as well as the history of the changes made to the transaction code.

## Lock a tran code

Because Twisp is an immutable database, we cannot fully "delete" a tran code. Instead, Twisp marks the tran code's status as `LOCKED`, which prevents transactions from posting using this version of tran code.

To delete (lock) an tran code, we can use the `deleteTranCode` mutation. We need to provide the `id` of the tran code we want to delete. Here's an example mutation:

**Request**

```graphql
mutation DeleteTranCode($tcBookTransferId: UUID!) {
  deleteTranCode(id: $tcBookTransferId) {
    tranCodeId
    status
  }
}
```
**Response**

```json
{
  "data": {
    "deleteTranCode": {
      "tranCodeId": "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855",
      "status": "LOCKED"
    }
  }
}
```
**Variables**

```json
{
  "tcBookTransferId": "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855"
}
```

Once the tran code is deleted, this mutation returns two fields: `tranCodeId` and `status`. `tranCodeId` is a UUID that uniquely identifies the deleted tran code, while `status` is the current status of the tran code (i.e. `LOCKED`).

This mutation is useful if you need to remove an tran code that is no longer needed or was created in error.

## Conclusion

This tutorial covered the basics of creating, modifying, and deleting transaction codes. Transaction codes play a critical role in identifying and categorizing transactions in the ledger, and designing them is an important part of using Twisp. By following the steps outlined in this tutorial, you should be able to create and manage transaction codes in your own ledger.
