1 structure Remind
:> REMIND
=
10 "-" ^
Real.fmt (StringCvt.FIX (SOME
2)) (~n
)
12 Real.fmt (StringCvt.FIX (SOME
2)) n
14 val basePerMonth
= 5.0
15 val deposit
= basePerMonth
* 3.0
19 val db
= C
.conn dbstring
21 val totalShares
= case C
.oneRow db
"SELECT SUM(shares) FROM WebUserPaying" of
22 [total
] => C
.intFromSql total
23 | _
=> raise Fail
"Bad SUM(shares) row"
25 fun doOne
[user
, members
, shares
, amount
] =
27 val user
= C
.stringFromSql user
28 val members
= C
.intFromSql members
29 val shares
= C
.intFromSql shares
30 val amount
= C
.realFromSql amount
32 val perMonth
= basePerMonth
* real shares
33 val headsUp
= deposit
+ perMonth
* 2.0
35 if amount
>= headsUp
then
40 fun write msg
= Mail
.mwrite (m
, msg
)
42 if amount
< deposit
then
43 write
"Subject: Your NEGATIVE HCoop balance\n"
45 write
"Subject: Your low HCoop balance\n";
46 write
"From: HCoop Payment Reminder Robot <payment";
52 write
"\nCc: payment@hcoop.net";
55 if amount
< deposit
then
56 (write
"Your HCoop balance is negative. This means that you've paid less than you've\n";
57 write
"been charged to date, excluding your required deposit. If your account hasn't\n";
58 write
"been frozen yet, expect that to happen very soon. Our bylaws allow our board\n";
59 write
"of directors to vote you out of the co-op, without any obligation to contact\n";
60 write
"you first, when your balance stays negative for three months. Please make a\n";
61 write
"payment as soon as possible, so that we don't need to do this!\n\n")
63 (write
"With our current dues projections, you have less than two months left until\n";
64 write
"your HCoop balance becomes negative, based on your sliding scale pledge amount.\n";
65 write
"Please make a payment as soon as you can. We will freeze your account if your\n";
66 write
"balance does become negative, and the board of directors will probably vote you\n";
67 write
"out of the cooperative shortly thereafter if you don't make a payment.\n\n");
69 write
"Your balance: US$";
70 write (printReal (amount
- deposit
));
71 write
"\nTotal number of members linked to your balance: ";
72 write (Int.toString members
);
73 write
"\nTotal pledge amount: ";
74 write (Int.toString shares
);
75 write
"\nDeposit: US$";
76 write (printReal deposit
);
77 write
"\nMinimum amount to pay to not see this message again for two months: US$";
78 write (printReal (headsUp
- amount
));
80 write
"\n\nThe deposit requirement was calculated as three months of dues at $5/mo..\n\n";
82 write
"To make a payment, visit:\n";
83 write
" https://members.hcoop.net/\n";
84 write
"and use the PayPal or Google Checkout link.\n";
86 write
"\nIf for whatever reason you don't plan to pay the amount suggested in this e-mail,\n";
87 write
"_please_ don't stay silent. Reply to this message explaining your circumstances.\n";
89 ignore (Mail
.mclose m
)
92 | doOne _
= raise Fail
"Bad SQL row"
94 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 < " ^ C
.realToSql (basePerMonth
* 5.0) ^
" * SUM(WebUserPaying.shares)");
97 end handle C
.Sql s
=> (print ("SQL failure: " ^ s ^
"\n");