1 structure Remind
:> REMIND
=
10 "-" ^
Real.fmt (StringCvt.FIX (SOME
2)) (~n
)
12 Real.fmt (StringCvt.FIX (SOME
2)) n
16 val db
= C
.conn dbstring
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"
22 fun doOne
[user
, members
, shares
, amount
] =
24 val user
= C
.stringFromSql user
25 val members
= C
.intFromSql members
26 val shares
= C
.intFromSql shares
27 val amount
= C
.realFromSql amount
29 val minimum
= 900.0 * real shares
/ real totalShares
* 2.0
31 if amount
>= minimum
then
36 fun write msg
= Mail
.mwrite (m
, msg
)
39 write
"Subject: Your NEGATIVE HCoop balance\n"
41 write
"Subject: Your low HCoop balance\n";
42 write
"From: HCoop Payment Reminder Robot <payment";
48 write
"\nCc: payment@hcoop.net";
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")
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");
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));
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";
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";
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";
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";
87 ignore (Mail
.mclose m
)
90 | doOne _
= raise Fail
"Bad SQL row"
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";
95 end handle C
.Sql s
=> (print ("SQL failure: " ^ s ^
"\n");