Paycheck Hub

Every check lands in the hub. Bills get paid first. What is left gets pushed out to the spokes by fixed rules, so no single place holds everything.

Bills spoke

Every bill gets turned into a per-check amount. Bills that hit rarely, like insurance, get held back a little each check so the money is there when the bill lands.

Bills per check

Where this check goes

Accounted for

Rules that fired

The algorithm

# Rule 0: turn every bill into a per-check amount (26 checks a year)
PER_CHECK = {"day": 14, "week": 2, "month": 12 / 26,
             "six_months": 2 / 26, "year": 1 / 26}

def bills_per_check(bill_list):
    return sum(amount * PER_CHECK[how_often]
               for name, amount, how_often in bill_list)

# rare bills (insurance) stay in the hub until due

def split(pay, travel, bills, base, floor_target, floor_now):
    income = pay - travel          # travel money repays what you already spent
    out = {"travel": travel}

    # Rule 1: bills come first, always
    if income <= bills:
        out["bills"] = income
        out["draw_from_floor"] = bills - income
        return out                 # every spoke pauses this check
    out["bills"] = bills
    left = income - bills

    # Rule 2: the normal part of the check uses fixed shares
    core = min(left, base - bills)
    extra = left - core
    room = max(0, floor_target - floor_now)

    floor_cut = core * 0.375
    to_floor = min(floor_cut, room)
    spill = floor_cut - to_floor   # floor full? its share moves on
    out["floor"]   = to_floor
    out["growth"]  = core * 0.3125 + spill * 0.5
    out["earner"]  = core * 0.1875 + spill * 0.5
    out["protect"] = core * 0.0625
    out["pocket"]  = core * 0.0625

    # Rule 3: overtime above a normal check
    if extra > 0:
        out["pocket"] += extra * 0.10
        rest = extra * 0.90
        room -= to_floor
        fill = min(rest, room)     # finish the floor first
        out["floor"]  += fill
        rest -= fill
        out["growth"] += rest * 5 / 9
        out["earner"] += rest * 4 / 9
    return out