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) | |
37 | in | |
38 | if amount < 0.0 then | |
39 | write "Subject: Your NEGATIVE HCoop balance\n" | |
40 | else | |
41 | write "Subject: Your low HCoop balance\n"; | |
42 | write "From: HCoop Payment Reminder Robot <payment"; | |
43 | write emailSuffix; | |
44 | write ">\n"; | |
45 | write "To: "; | |
46 | write user; | |
47 | write emailSuffix; | |
48 | write "\nCc: payment@hcoop.net"; | |
49 | write "\n\n"; | |
50 | ||
51 | if amount < 0.0 then | |
52 | (write "Your HCoop balance is negative. This means that you've paid less than you've\n"; | |
53 | write "been charged to date. Our bylaws allow our board of directors to vote you out\n"; | |
54 | write "of the co-op, without any obligation to contact you first, when your balance\n"; | |
55 | write "stays negative for three months. Please make a payment as soon as possible, so\n"; | |
56 | write "that we don't need to do this!\n\n") | |
57 | else | |
58 | (write "Your HCoop balance has dropped below your requested minimum, based on your\n"; | |
59 | write "sliding scale pledge amount. Please make a payment as soon as you can.\n\n"); | |
60 | ||
61 | write "Your balance: US$"; | |
62 | write (printReal amount); | |
63 | write "\nTotal number of members linked to your balance: "; | |
64 | write (Int.toString members); | |
65 | write "\nTotal pledge amount: "; | |
66 | write (Int.toString shares); | |
67 | write "\nRequested minimum: US$"; | |
68 | write (printReal (900.0 * real shares / real totalShares * 2.0)); | |
dda99898 | 69 | |
878a4e49 AC |
70 | write "\n\nYour minimum was calculated by dividing our total monthly expenses ($900) by the\n"; |
71 | write "sum of all members' pledge amounts, multiplying by your pledge amount, and then\n"; | |
72 | write "multiplying by 2. That is, the amount covers your share of two months' expenses.\n\n"; | |
dda99898 | 73 | |
878a4e49 AC |
74 | write "To make a payment, visit:\n"; |
75 | write " https://members2.hcoop.net/\n"; | |
76 | write "and use the PayPal or Google Checkout link.\n"; | |
9a4c122a AC |
77 | |
78 | write "\nIf you don't know how to get a username and password for members2.hcoop.net, visit:\n"; | |
79 | write " http://wiki2.hcoop.net/MemberManual/MigrationGuide\n"; | |
80 | write "for a reminder. (\"Step 1\" is all you need to read.)\n"; | |
81 | ||
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 |