> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vinmake.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Payments, rails and treasury

> What a payment posts, why every movement belongs to a rail, how an employee float behaves as a rail, and the loan and facility lifecycle.

# Payments, rails and treasury

Money never moves in GreatBook without belonging to a **rail**.

A rail is a channel money actually moves through - a bank account, a card, a cash box, an employee's float, a credit facility - and it reconciles against **its own** source: that bank's statement, that card's statement, that facility's statement, a physical count.
There is no single global cash check anywhere in the system, because a single global cash check passes while two rails are wrong in opposite directions.

## Paying a supplier

| Operation                      | Entry                                       |
| ------------------------------ | ------------------------------------------- |
| money out on a rail against AP | `Dr 2000` (331 AP) / `Cr <rail GL account>` |

The payment writes three kinds of row alongside the entry:

| Row               | What it says                                                                    |
| ----------------- | ------------------------------------------------------------------------------- |
| **settlement**    | this much money left this rail on this date, with its method and bank reference |
| **allocation**    | which obligations it paid, and how much of each                                 |
| **bank evidence** | when a statement line is matched to it, recorded separately from the booking    |

`unapplied = settlement amount - Σ allocations` is **derived**, never stored.
The Close list carries `payment_crossfoot` as a must-be-zero checksum, so an allocation with no settlement behind it - or a settlement whose allocations do not foot - is a break rather than a rounding difference.

## The rail accounts

| Rail                                                        | Type             | GL account    | Reconciles against            |
| ----------------------------------------------------------- | ---------------- | ------------- | ----------------------------- |
| `bank-vn`, `bank-hk-airwallex`, `alipay-hk`, `company-card` | company bank     | `1010`        | that account's statement      |
| `cash-fund`                                                 | cash on hand     | `1000`        | a cash box count              |
| `employee-float`                                            | employee float   | `1280` (141)  | the float holder's own ledger |
| `fac-factoring-vcb`, `fac-revolving-vcb`                    | finance facility | `2400` (341)  | the facility statement        |
| `loan-owner`                                                | finance facility | `2500` (3411) | the facility statement        |

The rail catalogue is itself a Close checksum: a movement on a rail the catalogue does not enumerate is a break, so a new payment channel cannot appear silently.

<Info>
  The per-rail reconciliation is **per rail × per currency**.
  One rail carrying two currencies produces two independent tie-outs, because a rail that nets across currencies can hide an FX error inside a correct-looking total.
</Info>

## The employee float is a rail, not an expense shortcut

An employee holding company cash is an **asset** of the company (`1280`, VAS 141), and every movement of it is booked.

| Movement                          | Entry                            |
| --------------------------------- | -------------------------------- |
| advance cash to the float         | `Dr 1280` (141) / `Cr <rail GL>` |
| the holder spends it              | `Dr <expense>` / `Cr 1280`       |
| the holder returns what is unused | `Dr <rail GL>` / `Cr 1280`       |

Paying a bill *out of* the float is the same `pay` operation with the float as the rail - and because the float's own GL account **is** `1280`, that path credits `1280` once and does not post a second float leg.
Double-crediting the float is the specific mistake the code comments against.

`float_gl_tie` is the Close checksum that ties the float's recorded movements to the `1280` balance.

## Supplier advances

| Operation                         | Entry                                                | Cash?  |
| --------------------------------- | ---------------------------------------------------- | ------ |
| advance money to a supplier       | `Dr 1150` (331 advance to supplier) / `Cr <rail GL>` | yes    |
| apply that advance against a bill | `Dr 2000` (331 AP) / `Cr 1150`                       | **no** |

The advance is an asset until it is applied - it is money the supplier holds that has not yet bought anything.
`po_advance_pool_settles` is the must-be-zero checksum over the pool, which is what makes an advance that was paid and never applied visible.

## Loans and facilities

One lifecycle covers every facility shape, and the balance is **derived** from movements rather than stored: `drawdown + interest accrued - principal repaid - interest paid`.

| Operation                  | Entry                                       |
| -------------------------- | ------------------------------------------- |
| drawdown                   | `Dr <rail>` / `Cr 2400` (341 facility loan) |
| interest accrual, at gross | `Dr 6210` (635 finance cost) / `Cr 2400`    |
| principal repayment        | `Dr 2400` / `Cr <rail>`                     |
| interest payment           | `Dr 2400` / `Cr <rail>`                     |
| a facility fee             | `Dr 6210` (635) / `Cr <rail>`               |

Accrued interest is added to what is owed rather than parked in a separate accrual, so the facility balance at any moment is the number the lender would quote.
Per-facility checksums cover the derived balance, the headroom against the limit, and the factoring positions.

<Note>
  `FACILITY-BAL`, `HEADROOM` and the factoring checksums are **per facility**, so the executed count of the Close list expands with the number of facilities on the book.
  That is one of the reasons a live run's check count and the 104 defined checksums are two different quantities.
</Note>

## Capital and dividends

| Operation                           | Entry                                                                              |
| ----------------------------------- | ---------------------------------------------------------------------------------- |
| owner injects capital               | `Dr 1010` (112 bank) / `Cr 3000` (411 capital)                                     |
| declare a dividend to an individual | `Dr 3100` (421 retained) / `Cr 2200` (338 payable) + `Cr 2220` (3335 PIT withheld) |

The 5% personal income tax on a dividend to an individual is withheld at declaration, not at payment, so the liability to the state exists from the moment the dividend does.

## Where it is enforced

| Concern                                                      | Code                                                                                             |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ |
| `pay`, `receive`, allocations, advances, deposits, the float | `backend/app/logics/finance/settlement.py`                                                       |
| the rail catalogue and each rail's GL account                | `backend/app/logics/finance/rails.py`                                                            |
| facilities, interest, repayment, factoring                   | `backend/app/logics/finance/loans.py`                                                            |
| capital and dividends                                        | `backend/app/logics/finance/consolidation.py`                                                    |
| derived balances - due, unapplied, pools, rail balances      | `backend/app/logics/finance/derive.py`                                                           |
| the ties                                                     | `payment_crossfoot`, `receipt_crossfoot`, `rail_catalog`, `rail_reconciliations`, `float_gl_tie` |

## The test that would fail if it broke

`backend/tests/test_settlement.py` covers the payment and allocation paths including the float's single-credit rule.
`backend/tests/test_close_checks.py` drives the cross-foot and per-rail reconciliation checksums against seeded breaks.

## Related

* [Settlement, rails and the AP/AR spine](/greatbook/capabilities/subledgers/settlement) - the sub-ledger, its rows and its rails
* [Loans, treasury and factoring](/greatbook/capabilities/subledgers/loans-treasury) - the facility family in full
* [Derived balances](/greatbook/capabilities/derived-balances) - why nothing here is a stored total
* [The Close checksums](/greatbook/capabilities/close-list) - how these ties are run and reported
