Skip to content

Security deposits

A security deposit isn’t revenue — it’s a liability. The tenant hands money to the landlord, the landlord holds it in trust, and at move-out either refunds it or retains parts of it against legitimate damages / unpaid rent. Canadian provinces differ on cooldown, interest, and maximum amounts; Kuberan handles the bookkeeping side and leaves the jurisdictional rules to the user.

The three moments

Intake Interest (optional) Disposition
│ │ │
│ [Record deposit] │ [Compute interest] │ [Post disposition]
├────────────────────────>├─────────────────────────────>│
Dr Cash pure helper Dr Deposits held × N
Cr Deposits held (JE posted manually) Cr target accounts
Cr Cash (refund)

1. Intake at move-in

When the tenant pays their deposit, record it from the Lease detail’s Record deposit intake button.

  1. Open the Lease detail.
  2. Click Record deposit intake in the header.
  3. Confirm the Amount (defaults to lease.deposit).
  4. Pick the Cash account the deposit is going into. Many operators use a separate trust account for deposits — if so, pick that one.
  5. Optional: override the Tenant deposits held liability account (the COA-wizard default is usually right).
  6. Click Record & post JE.

The JE:

Dr Cash deposit amount
Cr Tenant deposits held deposit amount

Both lines tagged with leaseId. Idempotent on lease:<id>:intake — re-running the button won’t create a duplicate entry.

The liability account is cached on lease.depositHeldInAccount so the disposition step later picks the same one without asking again.

2. Interest (optional, manual JE)

Provincial law in Ontario and a handful of other jurisdictions requires landlords to pay interest on last-month’s-rent deposits at a statutory rate (the guideline). v1 of Kuberan computes the interest amount but does not post the JE — the user reviews and posts manually.

  1. Open the Lease detail.
  2. Click Compute interest in the header.
  3. Enter the rate % (e.g. the current Ontario guideline — check the LTB site for the current year).
  4. Review the computed amount.
  5. Post a manual JE: Dr Interest expense / Cr Tenant deposits held (increases the tenant’s deposit balance).

The interest helper is pure — no database write. The computeAnnualDepositInterest function does deposit * ratePct / 100, rounded to cents.

Why manual? The timing varies (accrue monthly vs pay annually), the expense account isn’t always the same, and jurisdictions vary on whether you pay out or credit against next rent. Automating this reliably requires more jurisdiction-aware config than v1 carries.

3. Disposition at move-out

When the lease ends, the deposit is either refunded in full, retained in full, or split between deductions and refund. Itemise the deductions with the account each one credits (Repairs expense, Cleaning expense, Rent income for unpaid rent, etc.) and specify the refund amount. The server posts a single JE that zeros out the tenant’s liability.

  1. Open the Lease detail for the ended lease.
  2. Click Deposit disposition in the header.
  3. Add deduction rows: each has a Description, Amount, and Target account. Valid targets are any active expense, income, or AR account.
  4. Enter the Refund amount — the portion being returned to the tenant.
  5. If refund > 0, pick the Cash account the refund is drawn from.
  6. Click Post disposition.

The JE:

For each deduction:
Dr Tenant deposits held deduction amount
Cr <target account> deduction amount
If refund > 0:
Dr Tenant deposits held refund amount
Cr Cash refund amount

All lines tagged with leaseId. Tagging the deduction rows this way means a cleaning deduction from a $2,000 deposit doesn’t appear as a $2,000 line expense out of nowhere on the Property P&L — it’s the writedown of an existing liability, correctly attributed.

The full JE posts atomically. Idempotent on lease:<id>:disposition.

Validation: total deductions + refund must equal or be less than the original deposit (minus any prior partial dispositions). The server rejects over-allocations rather than silently over-drafting the liability.

Overdue refunds — the 10-day rule

Most Canadian jurisdictions require deposits to be refunded within 10 days of move-out. The Books Dashboard carries a widget that flags leases where:

  • status in ['ended', 'terminated']
  • deposit > 0
  • No disposition JE exists (no JE with sourceType='deposit' and sourceId='lease:<id>:disposition')
  • The lease ended more than 10 days ago

For leases without an explicit endDate (month-to-month roll-offs, legacy data), updatedAt is used as a fallback so those don’t silently disappear from the overdue list.

The widget shows the days overdue so you can prioritise oldest first.

Common pitfalls

Refund account pointing to the wrong bank: double-check the cash account on the disposition dialog. If the deposit was held in a trust account, the refund typically comes out of the same trust account, not the operating account.

Under-allocating: if deductions + refund < original deposit, there’s a residual liability balance. Either add another deduction or refund the remainder — don’t leave a dangling sub-balance.

Treating the intake as rent income: happens when the intake JE isn’t used and the user just records the cash receipt against rent. Fix: reverse the mis-posted JE and use the Record deposit intake button.