Skip to content

How dues are calculated

The bot computes a brother's owed amount per semester from four inputs:

member_due_cents  =  if assigned to a room  →  room.price_cents × share_fraction
                     else                   →  semester.due_amount_cents

paid_cents        =  sum of active payments for that brother in that semester
deducted_cents    =  sum of active deductions for that brother in that semester
credited_cents    =  paid_cents + deducted_cents

owed_cents        =  max(member_due_cents - credited_cents, 0)
overpaid_cents    =  max(credited_cents - member_due_cents, 0)

"Active" means undone_at is null. Undoing a payment or deduction immediately removes it from totals.

All amounts are stored as integer cents in Mongo. Dollar conversion happens only at the human edges (Discord input/output, XLSX cells).

Worked examples

Assume /set_semester 400. Brothers A, B, C, D are onboarded.

Example 1 — non-resident, paid in full

Brother A doesn't live in the house. Pays $400 cash on Sep 5.

Field Value
Room (none)
member_due_cents 40000 ($400)
paid_cents 40000 ($400)
deducted_cents 0
owed_cents 0

Status: Paid up.

Example 2 — sole occupant of a $2000 room

Brother B is alone in Room 1 (/set_room "Room 1" 2000, /assign_room "Room 1" @b).

Field Value
Room Room 1, share 1.0
member_due_cents 200000 ($2000) — covers the flat $400 + $1600 of rent
paid_cents 50000 ($500 paid so far)
owed_cents 150000 ($1500)

Note: B doesn't owe $400 + $2000. The room price already includes the dues. They owe $2000 total, period.

Example 3 — two brothers sharing a $2000 room

C and D share Room 2 (/set_room "Room 2" 2000, then /assign_room "Room 2" @c and /assign_room "Room 2" @d).

After the second /assign_room, the bot auto-rebalances both occupants to equal shares.

Brother Room Share Their due Notes
C Room 2 0.5 $1000 half of $2000
D Room 2 0.5 $1000 half of $2000

If C pays $400 and buys $200 of supplies (/deduct_dues @c 200 memo:"furniture"):

Field C's value
member_due_cents 100000 ($1000)
paid_cents 40000 ($400)
deducted_cents 20000 ($200)
credited_cents 60000 ($600)
owed_cents 40000 ($400)

Example 4 — unequal split

D wants the bigger half of Room 2; C is fine paying less. Treasurer overrides:

/set_share member:@d share_fraction:0.6
/set_share member:@c share_fraction:0.4
Brother Share Due
C 0.4 $800
D 0.6 $1200

Sum still equals the full room price. The bot doesn't enforce that occupants of one room sum to 1.0 — you might have a 3rd brother joining mid-semester and want to leave room.

Example 5 — overpaid

Brother A from Example 1 keeps paying. After total $500 paid:

Field Value
member_due_cents 40000
paid_cents 50000
owed_cents 0 (clamped, can't be negative)
overpaid_cents 10000 ($100)

Shown in /my_dues as a separate "Overpaid" field. Common for brothers who pay early for the next semester.

Edge cases

  • Brother becomes a resident mid-semester/assign_room flips their member_due_cents to room-based. Past payments still apply against the new (higher) total. They suddenly owe more than they paid.
  • Brother moves out mid-semester/unassign_room flips them back to the flat $400. If they already overpaid the room amount, they're now massively overpaid against the flat amount. We don't auto-refund — that's a treasurer judgment call.
  • No active semester (summer gap)/log_payment and /deduct_dues reject with "No active semester. Re-run after Fall starts."
  • Semester record exists but due_amount_cents=0 — happens if /set_semester was never run. All brothers show "owed: 0" with no error. Set the amount to fix.