Commit | Line | Data |
---|---|---|
dda99898 AC |
1 | structure Remind :> REMIND = |
2 | struct | |
3 | ||
4 | open Config | |
5 | ||
6 | structure C = PgClient | |
7 | ||
878a4e49 AC |
8 | fun printReal n = |
9 | if n < 0.0 then | |
10 | "-" ^ Real.fmt (StringCvt.FIX (SOME 2)) (~n) | |
11 | else | |
12 | Real.fmt (StringCvt.FIX (SOME 2)) n | |
13 | ||
dda99898 AC |
14 | fun main _ = |
15 | let | |
16 | val db = C.conn dbstring | |
17 | ||
878a4e49 AC |
18 | val totalShares = case C.oneRow db "SELECT SUM(shares) FROM WebUserPaying" of |
19 | [total] => C.intFromSql total | |
20 | | _ => raise Fail "Bad SUM(shares) row" | |
21 | ||
22 | fun doOne [user, members, shares, amount] = | |
23 | let | |
24 | val user = C.stringFromSql user | |
25 | val members = C.intFromSql members | |
26 | val shares = C.intFromSql shares | |
27 | val amount = C.realFromSql amount | |
28 | ||
29 | val minimum = 900.0 * real shares / real totalShares * 2.0 | |
30 | in | |
31 | if amount >= minimum then | |
32 | () | |
33 | else | |
34 | let | |
35 | val m = Mail.mopen () | |
36 | fun write msg = Mail.mwrite (m, msg) | |
4763cfb8 AC |
37 | |
38 | val minBal = 900.0 * real shares / real totalShares * 2.0 | |
878a4e49 AC |
39 | in |
40 | if amount < 0.0 then | |
41 | write "Subject: Your NEGATIVE HCoop balance\n" | |
42 | else | |
43 | write "Subject: Your low HCoop balance\n"; | |
44 | write "From: HCoop Payment Reminder Robot <payment"; | |
45 | write emailSuffix; | |
46 | write ">\n"; | |
47 | write "To: "; | |
48 | write user; | |
49 | write emailSuffix; | |
50 | write "\nCc: payment@hcoop.net"; | |
51 | write "\n\n"; | |
52 | ||
53 | if amount < 0.0 then | |
54 | (write "Your HCoop balance is negative. This means that you've paid less than you've\n"; | |
55 | write "been charged to date. Our bylaws allow our board of directors to vote you out\n"; | |
56 | write "of the co-op, without any obligation to contact you first, when your balance\n"; | |
57 | write "stays negative for three months. Please make a payment as soon as possible, so\n"; | |
58 | write "that we don't need to do this!\n\n") | |
59 | else | |
60 | (write "Your HCoop balance has dropped below your requested minimum, based on your\n"; | |
61 | write "sliding scale pledge amount. Please make a payment as soon as you can.\n\n"); | |
62 | ||
63 | write "Your balance: US$"; | |
64 | write (printReal amount); | |
65 | write "\nTotal number of members linked to your balance: "; | |
66 | write (Int.toString members); | |
67 | write "\nTotal pledge amount: "; | |
68 | write (Int.toString shares); | |
4763cfb8 AC |
69 | write "\nRequested minimum balance: US$"; |
70 | write (printReal minBal); | |
71 | write "\nPayment to get there: US$"; | |
72 | write (printReal (minBal - amount)); | |
dda99898 | 73 | |
878a4e49 AC |
74 | write "\n\nYour minimum was calculated by dividing our total monthly expenses ($900) by the\n"; |
75 | write "sum of all members' pledge amounts, multiplying by your pledge amount, and then\n"; | |
76 | write "multiplying by 2. That is, the amount covers your share of two months' expenses.\n\n"; | |
dda99898 | 77 | |
878a4e49 | 78 | write "To make a payment, visit:\n"; |
4763cfb8 | 79 | write " https://members.hcoop.net/\n"; |
878a4e49 | 80 | write "and use the PayPal or Google Checkout link.\n"; |
9a4c122a | 81 | |
9a4c122a AC |
82 | write "\nIf for whatever reason you don't plan to pay the amount suggested in this e-mail,\n"; |
83 | write "_please_ don't stay silent. Reply to this message explaining your circumstances.\n"; | |
84 | write "We are doing limited-time monetary grants on request, due to the extra costs\n"; | |
85 | write "associated with setting up our new servers.\n"; | |
86 | ||
878a4e49 AC |
87 | ignore (Mail.mclose m) |
88 | end | |
89 | end | |
90 | | doOne _ = raise Fail "Bad SQL row" | |
dda99898 | 91 | in |
878a4e49 | 92 | C.app db doOne "SELECT Balance.name, COUNT(*), SUM(WebUserPaying.shares) AS shrs, Balance.amount FROM WebUserPaying JOIN Balance ON WebUserPaying.bal = Balance.id GROUP BY Balance.name, Balance.amount HAVING amount < 10"; |
dda99898 AC |
93 | C.close db; |
94 | OS.Process.success | |
878a4e49 AC |
95 | end handle C.Sql s => (print ("SQL failure: " ^ s ^ "\n"); |
96 | OS.Process.failure) | |
dda99898 AC |
97 | |
98 | end |