> For the complete documentation index, see [llms.txt](https://devmosaic.gitbook.io/devmosaic/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://devmosaic.gitbook.io/devmosaic/resources/devmosaic-banking/migration.md).

# Migration

dm-banking includes migration commands for moving account and transaction data from older banking resources.

Supported migration sources:

* `Renewed-Banking`
* `qb-banking`
* `esx_banking`

All migration commands must be run from the server console. Players cannot run them in-game.

### Important Before You Start

1. Back up your database.
2. Keep the old banking database tables until migration is complete.
3. Stop scripts that may keep writing to the old banking tables during migration.
4. Start `dm-banking` and confirm the console says the schema is ready.
5. Run a dry run first.
6. Only run `apply` after checking the dry-run output.

### What Migration Imports

The migration attempts to import:

* personal accounts
* job accounts
* gang accounts
* shared accounts
* account balances
* shared account members
* account frozen state where available
* transactions / bank statements

The migration also sanitizes imported transaction labels so players do not see names like `Migrate QB Banking`, `QB Banking`, `ESX Banking`, or `Renewed-Banking` in normal transaction history.

### Renewed-Banking Migration

Renewed migration reads these old tables if they exist:

* `bank_accounts_new`
* `player_transactions`

It also reads player bank balances from:

* `players.money` on QBCore/Qbox
* `users.accounts` on ESX

#### Renewed Dry Run

Run:

```
dm-banking:migrate
```

This does not write data. It prints how many accounts, transactions, and ACL entries would be imported.

#### Renewed Apply

Run:

```
dm-banking:migrate apply
```

This writes the migrated data into `dm-banking`.

#### Renewed Export Option

You can also call:

```lua
exports['dm-banking']:migrateFromRenewed(true)
```

Use `false` or omit `true` for a dry run.

### qb-banking Migration

QB migration reads these tables if they exist:

* `players`
* `bank_accounts`
* `bank_statements`

It imports player bank balances from:

```
players.money
```

It imports personal account names from:

```
players.charinfo
```

#### QB Dry Run

Run either command:

```
dm-banking:migrate qb
```

or:

```
dm-banking:migrate:qb
```

This only prints the migration summary.

#### QB Apply

Run either command:

```
dm-banking:migrate qb apply
```

or:

```
dm-banking:migrate:qb apply
```

This writes the migrated data.

#### QB Export Option

```lua
exports['dm-banking']:migrateFromQbBanking(true)
```

Use `false` or omit `true` for a dry run.

### esx\_banking Migration

ESX migration reads these tables if they exist:

* `users`
* `banking`

It imports player bank balances from:

```
users.accounts
```

It imports names from:

```
users.firstname
users.lastname
```

if those columns exist.

#### ESX Dry Run

Run either command:

```
dm-banking:migrate esx
```

or:

```
dm-banking:migrate:esx
```

#### ESX Apply

Run either command:

```
dm-banking:migrate esx apply
```

or:

```
dm-banking:migrate:esx apply
```

#### ESX Export Option

```lua
exports['dm-banking']:migrateFromEsxBanking(true)
```

Use `false` or omit `true` for a dry run.

### After Migration

Check the following before opening the server to players:

* personal account balances
* job account balances
* gang account balances
* shared account balances
* shared account members
* transaction history
* frozen accounts
* ATM withdrawals
* deposits
* transfers

Then disable the old banking resource.

### Common Migration Console Output

Dry run example:

```
[dm-banking][migrate:qb] === DRY RUN ===
[dm-banking][migrate:qb] players: 120 rows
[dm-banking][migrate:qb] bank_accounts: 8 rows
[dm-banking][migrate:qb] bank_statements: 2450 rows
[dm-banking][migrate:qb] DRY RUN done - accounts: 128, transactions: 2450, acl entries: 140
```

Apply example:

```
[dm-banking][migrate:qb] === APPLY ===
[dm-banking][migrate:qb] APPLY done - accounts: 128, transactions: 2450, acl entries: 140
```

### If Balances Are Missing

Check that the original framework tables still exist:

QBCore/Qbox:

```
players.money
```

ESX:

```
users.accounts
```

QB shared/job/gang accounts:

```
bank_accounts.account_balance
```

Renewed accounts:

```
bank_accounts_new.amount
```

### If Transactions Show Old Script Names

The migration sanitizes known imported labels. If you still see old names, check `server/migrate_legacy.lua` or `server/migrate_renewed.lua` and add that label to the sanitize query before running migration again.

Known names already cleaned:

* `QB Banking`
* `qb-banking`
* `Migrate QB Banking`
* `ESX Banking`
* `esx_banking`
* `Renewed-Banking`
* `renewed-banking`

### Safe Re-Run Notes

Migration uses stable transaction ids for many imports and updates existing accounts where possible, but you should still avoid repeated apply runs unless you have a database backup and understand what changed.

Recommended:

1. Dry run.
2. Apply once.
3. Verify.
4. Disable old banking resource.
