Annotate freezeworthy list with whether members joined this month
[bpt/portal.git] / money.sml
index e077fcc..6701459 100644 (file)
--- a/money.sml
+++ b/money.sml
@@ -276,42 +276,42 @@ fun costBase amt =
 val monthlyCost = 900.0
 val graceMonths = 1
 
+val baseDues = 5.0
+
 fun delinquentPledgers () =
     let
-       val costBase = costBase monthlyCost
-
        fun makeRow [id, name, shares, amount] = {id = C.intFromSql id, name = C.stringFromSql name,
                                                  shares = C.intFromSql shares, balance = C.realFromSql amount}
          | makeRow row = Init.rowError ("Bad delinquentPledgers", row)
     in
        C.map (getDb ()) makeRow ($`SELECT WebUserPaying.id, WebUserPaying.name, shares, amount
                                    FROM WebUserPaying JOIN Balance ON Balance.id = bal
-                                   WHERE amount < shares * ^(C.realToSql costBase) * ^(C.intToSql graceMonths)
+                                   WHERE amount < shares * ^(C.realToSql baseDues) * ^(C.intToSql graceMonths)
                                      AND shares > 1
                                    ORDER BY name`)
     end
 
 fun resetPledges ids =
-    raise Fail ($`UPDATE WebUser SET shares = 1 WHERE id IN (^(String.concatWith ", " (List.map C.intToSql ids)))`)
+    ignore (C.dml (getDb ()) ($`UPDATE WebUser SET shares = 1 WHERE id IN (^(String.concatWith ", " (List.map C.intToSql ids)))`))
 
 fun freezeworthyPledgers () =
     let
-       val costBase = costBase monthlyCost
+       val baseDues = 5.0
 
-       fun makeRow [id, name, amount] = {id = C.intFromSql id, name = C.stringFromSql name,
-                                         balance = C.realFromSql amount}
+       fun makeRow [id, name, amount, j] = {id = C.intFromSql id, name = C.stringFromSql name,
+                                            balance = C.realFromSql amount, joinedThisMonth = C.boolFromSql j}
          | makeRow row = Init.rowError ("Bad freezeworthyPledgers", row)
     in
-       C.map (getDb ()) makeRow ($`SELECT WebUserPaying.id, WebUserPaying.name, amount
+       C.map (getDb ()) makeRow ($`SELECT WebUserPaying.id, WebUserPaying.name, amount, CURRENT_TIMESTAMP - joined < INTERVAL '1 month'
                                    FROM WebUserPaying JOIN Balance ON Balance.id = bal
-                                   WHERE amount >= ^(C.realToSql costBase) * ^(C.intToSql graceMonths)
-                                     AND amount < ^(C.realToSql costBase) * ^(C.intToSql (graceMonths + 1))
+                                   WHERE amount >= ^(C.realToSql baseDues) * ^(C.intToSql graceMonths)
+                                     AND amount < ^(C.realToSql baseDues) * ^(C.intToSql (graceMonths + 1))
                                    ORDER BY name`)
     end
 
 fun bootworthyPledgers () =
     let
-       val costBase = costBase monthlyCost
+       val baseDues = 5.0
 
        fun makeRow [id, name, amount] = {id = C.intFromSql id, name = C.stringFromSql name,
                                          balance = C.realFromSql amount}
@@ -319,8 +319,47 @@ fun bootworthyPledgers () =
     in
        C.map (getDb ()) makeRow ($`SELECT WebUserPaying.id, WebUserPaying.name, amount
                                    FROM WebUserPaying JOIN Balance ON Balance.id = bal
-                                   WHERE amount < ^(C.realToSql costBase) * ^(C.intToSql graceMonths)
+                                   WHERE amount < ^(C.realToSql baseDues) * ^(C.intToSql graceMonths)
                                    ORDER BY name`)
     end
 
+fun billDues {descr, base, date} =
+    let
+       val db = getDb ()
+       val paying =
+           case Group.groupNameToId "paying" of
+               NONE => raise Fail "No 'paying' group"
+             | SOME id => id
+
+       val shares =
+           case C.oneRow db ($`SELECT SUM(shares)
+                                 FROM WebUser JOIN Membership ON usr = WebUser.id AND grp = ^(C.intToSql paying)`) of
+               [n] => C.intFromSql n
+             | row => Init.rowError ("Bad addHostingCharges share count result", row)
+
+       val total = real shares * base
+
+       val give = addTransaction (descr, ~total, date)
+
+       fun doUser [uid, shares]  =
+           let
+               val uid = C.intFromSql uid
+               val shares = C.intFromSql shares
+           in
+               addCharge {trn = give, usr = uid, amount = ~(base * real shares)}
+           end
+         | doUser r = Init.rowError ("Bad billDues/doUser row", r)
+
+       val receive = addTransaction (descr, total, date)
+
+       val hcoop = valOf (Init.userNameToId "hcoop")
+    in
+       C.app db doUser ($`SELECT id, shares
+                          FROM WebUser JOIN Membership ON usr = WebUser.id AND grp = ^(C.intToSql paying)`);
+       applyCharges give;
+       
+       addCharge {trn = receive, usr = hcoop, amount = total};
+       applyCharges receive
+    end
+
 end