# Accounting Run Overview

> Source: [Accounting Run (Notion)](https://www.notion.so/c9ecc13c18cb4362962ce54853992580)  
> Last updated in Notion: February 2024

## What Is an Accounting Run?

The accounting run is Abacus's core process for calculating royalties. It matches sales transactions to contracts, applies negotiated term rates, handles currency conversion, and produces ledger entries that determine how much each client is owed.

## Entity Hierarchy

```
Statement Period
  └── Accounting Period  (has a contract_type)
        ├── Sales File
        └── Accounting Run  (instance of a Run Controller)
```

- **Statement Period** — top-level time boundary; exchange rates attach here.
- **Accounting Period** — scoped by `contract_type` (distribution, neighbouring_rights, etc.). Only one can be open per contract type at a time.
- **Sales File** — a batch of transaction data delivered by Finance. Sibling to the accounting run.
- **Accounting Run** — an instance of a **Run Controller**, which groups contracts of the same type.

## Contract Types

| Type | Alias | Description |
|------|-------|-------------|
| `distribution` | "label run" | Royalties earned on products/tracks distributed to DSPs (Spotify, Apple, etc.) |
| `neighbouring_rights` | "performer/PNR run" | Royalties earned on public broadcast/performance of sound recordings via CMOs |
| `publishing` | — | Royalties earned from published compositions (not supported as a native Abacus run type; processed as manual adjustments via Snowflake — see [Publishing Sales](../runbooks/publishing-sales.md)) |

## Data Sources

Transaction-level data lives in **Snowflake** (`ROYALTY_ACCOUNTING` schema). Summary/rollup data lives in **MySQL** (`royalty_accounting` database). Airflow DAGs and lambdas bridge the two during an accounting period.

### Key Snowflake Tables

| Table | Description |
|-------|-------------|
| `stmt_db_sales_distro` | Distribution sales transactions (from Finance) |
| `stmt_db_sales_nr` | Neighbouring rights sales transactions |
| `contract_denormalized_distro` | Flattened/cartesian join of contract terms and conditions |
| `contract_transaction_staging` | Matched sales-to-contract mappings (pre-approval) |
| `accounting_run_results_distro_staging` | Calculated results (pre-approval) |
| `accounting_run_results_distro` | Committed results (post-approval) |
| `contract_transaction_distro` | Committed contract-transaction mappings (post-approval) |

### Key MySQL Tables (royalty_accounting)

| Table | Description |
|-------|-------------|
| `sales_file` | Sales file metadata (name, checksums, row counts) |
| `exchange_rate` | Currency exchange rates per statement period |
| `ledger_accounting_run_balance` | Run summary — total revenue per contract per run |
| `ledger_account_contract` | Account-level ledger balances (committed royalties) |
| `ledger_deposit` | Rounding remainders from ledger commits |
| `ledger_reserve_taken` | Physical reserves taken during distribution runs |

## Exchange Rates

Exchange rates are uploaded and attached to the parent **statement period** each month. They are used during the calculation step to convert between sale currency, USD, and the client's preferred payee currency.

Example `exchange_rate` entries:

| from_currency | to_currency | rate |
|--------------|-------------|------|
| CAD | USD | 0.750161 |
| EUR | USD | 0.989900 |
| BRL | USD | 0.191019 |
| USD | GBP | 0.883686 |

## Sales Files

Sales data arrives from Finance and is ingested into Snowflake staging tables. Key points:

- Distribution sales: `stmt_db_sales_distro` — columns include store_id, country_id, transaction_type, UPC, ISRC, quantity, unit_price_usd, total_usd, withholding_tax_usd.
- NR sales: `stmt_db_sales_nr` — similar but includes contributor and sound recording identifiers.
- The `sales_file_id` in Snowflake references the MySQL `royalty_accounting.sales_file` primary key.
- Not every column is used in the royalty calculation; some serve BI/Customer Accounting/analytics downstream.

For details on how sales are delivered from Finance to Abacus, see:
- [Sales File Delivery (Whimsical)](https://whimsical.com/sales-file-delivery-overview-CtLQfs3u6Hm1A3jKBjvKMg)
- [Sales Processing Notes (Notion)](https://www.notion.so/7205572d7fc24a40a75cdd400c18b5ea)

## Run Controller

A **run controller** is a named grouping of contracts, all of the same `contract_type`. An **accounting run** is an instance of a run controller for a specific accounting period.

Key behaviors:
- Users can **Create** a run (triggers calculation), **Approve** it (commits to ledgers), or **Invalidate** it (starts fresh).
- Run controllers in different groups don't see each other's contracts, which can lead to "double-booked" revenue if the same UPC/ISRC appears in contracts across multiple controllers. Sibling contracts should be in the same run controller.
- Controllers should be run one at a time.
