code wiki / (root) / nx_bills.nx

nx_bills.nx source

↩ module page · 62 lines · 2631 B

1// nx_bills.nx -- R1 of THE NISHI SITUATION-MANAGEMENT arc: the recurring BILLS / OBLIGATIONS register 2// (insurance, mortgage, HOA, utilities, ...). The ledger tracks what HAPPENED; this tracks what is COMMITTED 3// and what is DUE. Exact no-float (nx_money): a bill carries an amount (cents), a cadence in months 4// (1=monthly, 3=quarterly, 6=semiannual, 12=annual), a due day-of-month, a category code, and a paid-this- 5// period flag. Computes the true MONTHLY obligation (cadence-normalized), per-category totals, what is DUE 6// SOON, and what is OVERDUE -- so a person sees their whole picture and never misses a bill. Data-driven, 7// no hardware writes. license_tier: ORIGINAL 8import "nx_syscalls.nx" 9import "nx_money.nx" 10 11// category codes (DATA convention): 0 housing, 1 insurance, 2 utility, 3 debt, 4 other. 12const BL_HOUSING: i64 = 0 13const BL_INSURANCE: i64 = 1 14const BL_UTILITY: i64 = 2 15const BL_DEBT: i64 = 3 16const BL_OTHER: i64 = 4 17 18// monthly-equivalent of one bill = amount / cadence_months, exact (banker's rounding). 19func bl_monthly(amount: i64, cadence_months: i64) -> i64 { 20 if cadence_months <= 0 { return amount } 21 return mny_div_round(amount, cadence_months, RND_HALF_EVEN) 22} 23 24// total monthly obligation across n bills. 25func bl_monthly_total(amounts: *i64, cadences: *i64, n: i64) -> i64 { 26 var t: i64 = 0 27 var i: i64 = 0 28 while i < n { t = mny_add(t, bl_monthly(amounts[i], cadences[i])); i = i + 1 } 29 return t 30} 31 32// monthly obligation for one category. 33func bl_category_monthly(amounts: *i64, cadences: *i64, cats: *i64, n: i64, target: i64) -> i64 { 34 var t: i64 = 0 35 var i: i64 = 0 36 while i < n { if cats[i] == target { t = mny_add(t, bl_monthly(amounts[i], cadences[i])) } i = i + 1 } 37 return t 38} 39 40// bills due within `window` days of `today` (both are day-of-month 1..31). writes their indices to 41// out_idx[]; returns the count. (In-month window; cross-month wrap is the refinement.) 42func bl_due_soon(due_days: *i64, today: i64, window: i64, n: i64, out_idx: *i64) -> i64 { 43 var c: i64 = 0 44 var i: i64 = 0 45 while i < n { 46 let d: i64 = due_days[i] 47 if d >= today { if (d - today) <= window { out_idx[c] = i; c = c + 1 } } 48 i = i + 1 49 } 50 return c 51} 52 53// overdue bills: due day already passed this period AND not paid (paid[i]==0). writes indices; returns count. 54func bl_overdue(due_days: *i64, paid: *i64, today: i64, n: i64, out_idx: *i64) -> i64 { 55 var c: i64 = 0 56 var i: i64 = 0 57 while i < n { 58 if due_days[i] < today { if paid[i] == 0 { out_idx[c] = i; c = c + 1 } } 59 i = i + 1 60 } 61 return c 62}