# Panel Invoice Screen Hooks

https://dev.wisecp.com/es/admin-invoice-screen-hooks

The twenty-three placement points of the invoice, cash book and coupon screens: the invoice detail, summary cards, list toolbars and forms.

## Overview

The placement points of the invoice, cash book and coupon screens live here: the sections of the invoice detail, the list toolbars and the coupon and currency forms.

The invoice summary point hands you the arithmetic already done: the **balance left** and the **total paid**. In the cash summary each value arrives in two forms; use the raw one when you calculate.

## Reference

### A badge or button in the invoice title

uiadmin.invoices_detail.header_actions

`admin/invoices/detail` the title area

Appears in the title row of the invoice detail. It suits its counterpart in your accounting system or a shortcut of your own.

Parameters 2

$invoicearrayThe active invoice record.

$invoice_idintThe invoice id.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_detail.header_actions', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### The top of the invoice summary card

uiadmin.invoice_detail.summary_card_top

`admin/invoices/detail` the balance in hand

Appears at the very top of the summary card. The balance left and the total paid are in your hands.

Parameters 4

$invoicearrayThe active invoice record.

$invoice_idintThe invoice id.

$balancefloatThe balance left. Above zero means the invoice is still unpaid; it is filled on a partial payment too.

$total_paidfloatThe total paid so far.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoice_detail.summary_card_top', 10,
    function ($invoice, $invoice_id, $balance, $total_paid) {
        // Kismi odemede de bakiye dolu gelir.
        if ($balance <= 0 || $total_paid <= 0) return null;

        return '<div class="alert alert-info">Kismi odeme</div>';
    });
```

### The bottom of the invoice summary

uiadmin.invoices_detail.summary.bottom

`admin/invoices/detail` below the summary

Appears after the lines of the summary card.

Parameters 2

$invoicearrayThe active invoice record.

$invoice_idintThe invoice id.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_detail.summary.bottom', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### The top of the payments section

uiadmin.invoices_detail.payments.top

`admin/invoices/detail` the payment list

Appears above the list of payments recorded against the invoice.

Parameters 3

$invoicearrayThe active invoice record.

$invoice_idintThe invoice id.

$paymentsarrayThe payment records of the invoice.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_detail.payments.top', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### A new tab on the invoice detail

uiadmin.invoice_detail.tabs

`admin/invoices/detail` an object, not an array

Runs once the invoice tabs are built. You do not return HTML: you add the tab through the object’s method.

Parameters 2

$tabobjectThe tab object.

$invoicearrayThe full invoice record.

Return 1

voidThe return is **not used**. This point shows no HTML.

Listener PHP

```php
Hook::add('ui:admin.invoice_detail.tabs', 10, function ($tab, $invoice) {
    $tab->add('acme', 'Acme', Acme::renderTab((int) ($invoice['id'] ?? 0)));
});
```

### The very bottom of the invoice page

uiadmin.invoices_detail.bottom

`admin/invoices/detail` end of the page

Appears at the very end of the page.

Parameters 2

$invoicearrayThe active invoice record.

$invoice_idintThe invoice id.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_detail.bottom', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### Beside the invoice list summary cards

uiadmin.invoices_list.stats

`admin/invoices` data after the filter

Appears beside the summary cards above the list. It puts a card of your own next to the core ones.

Parameters 1

$initial_statsarrayThe summary data worked out: unpaid, paid and overdue. This is the data **after the summary filter ran**: a change you made there shows up here.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_list.stats', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### Above the table on the invoice list

uiadmin.invoices_list.before_table

`admin/invoices` no parameters

Appears immediately above the invoice table.

Parameters 0

—It takes no parameters.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_list.before_table', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### The invoice list toolbar

uiadmin.invoice_list.toolbar

`admin/invoices` no parameters

Appears in the toolbar of the invoice list.

Parameters 0

—It takes no parameters.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoice_list.toolbar', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### The cash book toolbar

uiadmin.invoices_cash.toolbar

`admin/money` no parameters

Appears in the toolbar of the income and expense book.

Parameters 0

—It takes no parameters.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_cash.toolbar', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### Above the table on the cash book

uiadmin.invoices_cash.before_table

`admin/money` no parameters

Appears immediately above the cash book table.

Parameters 0

—It takes no parameters.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_cash.before_table', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### Above the table on the recurring expense list

uiadmin.invoices_periodic_expenses.before_table

`admin/money` no parameters

Appears immediately above the recurring expense table.

Parameters 0

—It takes no parameters.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_periodic_expenses.before_table', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### The recurring expense toolbar

uiadmin.invoices_periodic_expenses.toolbar

`admin/money` no parameters

Appears in the toolbar of the recurring expense list.

Parameters 0

—It takes no parameters.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_periodic_expenses.toolbar', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### The coupon list toolbar

uiadmin.coupon_list.toolbar

`admin/money` no parameters

Appears in the toolbar of the coupon list.

Parameters 0

—It takes no parameters.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.coupon_list.toolbar', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### Above the table on the coupon list

uiadmin.coupon_list.before_table

`admin/money` no parameters

Appears immediately above the coupon table.

Parameters 0

—It takes no parameters.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.coupon_list.before_table', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### The currency list toolbar

uiadmin.currency_list.toolbar

`admin/money` no parameters

Appears in the toolbar of the currency list.

Parameters 0

—It takes no parameters.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.currency_list.toolbar', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### Above the table on the currency list

uiadmin.currency_list.before_table

`admin/money` no parameters

Appears immediately above the currency table.

Parameters 0

—It takes no parameters.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.currency_list.before_table', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### Below the cash book summary

uiadmin.invoices_cash.summary.after

`admin/money` raw and formatted together

Appears below the income and expense summary.

Parameters 1

$summaryarrayThe cash summary: income, expense and balance. Each value arrives in **two forms**: a raw number for arithmetic and formatted text for the screen. Use the raw one when comparing.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_cash.summary.after', 10, function ($summary) {
    // Karsilastirmada HAM degeri kullanin, bicimli metni degil.
    if ((float) ($summary['balance'] ?? 0) >= 0) return null;

    return '<div class="alert alert-warning">Kasa eksi bakiyede</div>';
});
```

### Above the invoice creation form

uiadmin.invoices_edit.before_content

`admin/invoices` the customer may be zero

Appears above the manual invoice form.

Parameters 1

$user_idintThe customer the invoice is for. It is **zero** when no customer is chosen yet.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_edit.before_content', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### Below the invoice creation form

uiadmin.invoices_edit.bottom

`admin/invoices` the customer may be zero

Appears below the same form.

Parameters 1

$user_idintThe customer the invoice is for. It is **zero** when no customer is chosen yet.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.invoices_edit.bottom', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### Above the coupon form

uiadmin.coupon_edit.before_content

`admin/money` two modes

Appears above the coupon add and edit form.

Parameters 2

$coupon_idintThe coupon id; **zero when creating**.

$isEditboolWhether this is the edit mode.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.coupon_edit.before_content', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### Below the coupon form

uiadmin.coupon_edit.bottom

`admin/money` two modes

Appears below the same form.

Parameters 2

$coupon_idintThe coupon id; **zero when creating**.

$isEditboolWhether this is the edit mode.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.coupon_edit.bottom', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

### The coupon summary column

uiadmin.coupon_edit.summary_sidebar

`admin/money` the side column

Appears in the summary column beside the coupon form.

Parameters 1

$coupon_idintThe coupon id; zero when creating.

Return 1

string|nullThe **HTML you return appears**. With several listeners the outputs are appended one after another in priority order. Empty text, `null` and `false` are skipped, so return `null` when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.

Listener PHP

```php
Hook::add('ui:admin.coupon_edit.summary_sidebar', 10, function () {
    return '<div class="alert alert-info">Acme</div>';
});
```

## Pitfalls

> **Do not calculate with the formatted value**
> 
> In the cash summary every amount exists in two forms: a raw number and the **formatted text** meant for the screen. That text carries a thousands separator and a currency symbol; a listener converting it back to a number gets the wrong answer on every amount large enough to have a separator.

> **A filled balance does not mean nothing was paid**
> 
> The balance left in the invoice summary is **also filled on a partial payment**. A listener assuming "a balance means no payment" treats a half-paid invoice as unpaid. Look at the total paid as well.

## Related Articles

- [Invoice Lifecycle Hooks](https://dev.wisecp.com/en/invoice-lifecycle-hooks)
- [Invoice Amount Hooks](https://dev.wisecp.com/en/invoice-amount-hooks)
- [Management Panel Hooks](https://dev.wisecp.com/en/hooks-in-the-management-panel)
