cvsimport
[hcoop/zz_old/portal.git] / money.mlt
1 <% @header [("title", ["MoneyMatters"])];
2
3 val root = Group.inGroupNum 0;
4
5 ref showNormal = true;
6
7 if $"hist" <> "" then
8 showNormal := false;
9 val id = Web.stoi ($"hist") %>
10 <table>
11 <tr> <td><b>Date</b></td> <td><b>Description</b></td> <td><b>Amount</b></td> </tr>
12 <% foreach (amount, trn) in Money.listUserTransactions id do %>
13 <tr> <td><% #d trn %></td> <td><a href="money?trn=<% #id trn %>"><% Web.html (#descr trn) %></a></td> <td><% amount %>/<% #amount trn %></td> </tr>
14 <% end %>
15 </table>
16
17 <% elseif $"cmd" = "list" then
18 val admin = Group.inGroupName "money";
19 showNormal := false %>
20
21 <h3>Transactions</h3>
22
23 <table>
24 <tr> <td><b>Date</b></td> <td><b>Description</b></td> <td><b>Amount</b></td> <td><b>Last modified</b></td> <td><b>Participants</b></td> </tr>
25 <% foreach trn in Money.listTransactions () do %>
26 <tr> <td><% #d trn %></td> <td><a href="money?trn=<% #id trn %>"><% Web.html (#descr trn) %></a></td> <td><% #amount trn %></td> <td><% #stamp trn %></td>
27 <% switch Money.listChargesWithNames (#id trn) of
28 [(name, cha)] => %><td><a href="user?id=<% #usr cha %>"><% name %></a></td><%
29 | _ => %><td><i>multi</i></td><%
30 end;
31 if admin then
32 %><td><a href="money?modHosting=<% #id trn %>">[Hosting]</a> <a href="money?modPay=<% #id trn %>">[Payment]</a> <a href="money?modEven=<% #id trn %>">[Other]</a></td>
33 <td><a href="money?del=<% #id trn %>">[Delete]</a></td><%
34 end
35 %></tr><%
36 end %>
37 </table>
38
39 <% elseif $"cmd" = "bals" then
40 showNormal := false %>
41
42 <h3>Active Balances</h3>
43
44 <table>
45 <% foreach bal in Balance.listOwnedBalances () do %>
46 <tr><td><% #name bal %></td> <td><% #amount bal %></td> <td>
47 <% switch Balance.listBalanceUsers (#id bal) of
48 [] =>
49 | (user :: users) =>
50 %><a href="money?hist=<% #id user %>"><% Web.html (#name user) %></a><%
51 foreach user in users do
52 %>, <a href="money?hist=<% # id user %>"><% Web.html (#name user) %></a><%
53 end
54 end %></td> </tr>
55 <% end %>
56 </table>
57
58 <% elseif $"cmd" = "deadbals" then
59 showNormal := false %>
60
61 <h3>Retired Balances</h3>
62
63 <table>
64 <% foreach bal in Balance.listUnownedBalances () do %>
65 <tr><td><% #name bal %></td> <td><% #amount bal %></td> <td>
66 <% switch Balance.listBalanceUsers (#id bal) of
67 [] =>
68 | (user :: users) =>
69 %><a href="user?id=<% #id user %>"><% Web.html (#name user) %></a> <a href="money?hist=<% #id user %>">[History]</a><%
70 foreach user in users do
71 %>, <a href="user?id=<% #id user %>"><% Web.html (#name user) %></a> <a href="money?hist=<% #id user %>">[History]</a><%
72 end
73 end %></td> </tr>
74 <% end %>
75 </table>
76
77 <% elseif $"cmd" = "nbals" then
78 showNormal := false;
79 val bals = Balance.listNegativeOwnedBalances () %>
80
81 <h3>Negative Active Balances (<% length bals %>)</h3>
82
83 <table>
84 <% foreach bal in bals do %>
85 <tr><td><% #name bal %></td> <td><% #amount bal %></td> <td>
86 <% switch Balance.listBalanceUsers (#id bal) of
87 [] =>
88 | (user :: users) =>
89 %><a href="user?id=<% #id user %>"><% Web.html (#name user) %></a> <a href="money?hist=<% #id user %>">[History]</a><%
90 foreach user in users do
91 %>, <a href="user?id=<% #id user %>"><% Web.html (#name user) %></a> <a href="money?hist=<% #id user %>">[History]</a><%
92 end
93 end %></td> </tr>
94 <% end %>
95 </table>
96
97 <% elseif $"cmd" = "hosting" then
98 Group.requireGroupName "money";
99 showNormal := false %>
100
101 <h3>New hosting bill</h3>
102
103 <form action="money" method="post">
104 <input type="hidden" name="cmd" value="hosting2">
105 <table class="blanks">
106 <tr> <td>Description:</td> <td><input name="descr"></td> </tr>
107 <tr> <td>Date:</td> <td><input name="d"></td> </tr>
108 <tr> <td>Amount:</td> <td><input name="amount"></td> </tr>
109 <tr> <td>Free bandwidth cutoff (MB):</td> <td><input name="cutoff" value="200"></td> </tr>
110 <tr> <td>Cost/GB:</td> <td><input name="cost" value="4"></td> </tr>
111 <tr> <td>Member usage:</td> <td><textarea wrap="soft" name="usage" rows="24" cols="80"></textarea></td> </tr>
112 <tr> <td><input type="submit" value="Add"></td> </tr>
113 </table>
114
115 <% elseif $"cmd" = "hosting2" then
116 Group.requireGroupName "money";
117 val id = Money.addTransaction ($"descr", Util.neg (Web.stor ($"amount")), $"d");
118 Money.addHostingCharges {trn = id, cutoff = 1000 * Web.stoi ($"cutoff"), cost = Web.stor ($"cost"), usage = $"usage"};
119
120 %><h3>Hosting transaction added.</h3>
121
122 <% elseif $"modHosting" <> "" then
123 Group.requireGroupName "money";
124 showNormal := false;
125 val id = Web.stoi ($"modHosting");
126 val trn = Money.lookupTransaction id %>
127
128 <h3>Modify hosting bill</h3>
129
130 <form action="money" method="post">
131 <input type="hidden" name="saveHosting" value="<% id %>">
132 <table class="blanks">
133 <tr> <td>Description:</td> <td><input name="descr" value="<% Web.html (#descr trn) %>"></td> </tr>
134 <tr> <td>Date:</td> <td><input name="d" value="<% Web.html (#d trn) %>"></td> </tr>
135 <tr> <td>Amount:</td> <td><input name="amount" value="<% Util.neg (#amount trn) %>"></td> </tr>
136 <tr> <td>Free bandwidth cutoff (MB):</td> <td><input name="cutoff" value="200"></td> </tr>
137 <tr> <td>Cost/GB:</td> <td><input name="cost" value="4"></td> </tr>
138 <tr> <td>Member usage:</td> <td><textarea wrap="soft" name="usage" rows="24" cols="80"><%
139 switch Money.lookupHostingUsage id of
140 SOME s => s
141 end %></textarea></td> </tr>
142 <tr> <td><input type="submit" value="Save"></td> </tr>
143 </table>
144
145 <% elseif $"saveHosting" <> "" then
146 Group.requireGroupName "money";
147 val id = Web.stoi ($"saveHosting");
148 val trn = Money.lookupTransaction id;
149
150 Money.clearCharges id;
151 Money.modTransaction {trn with descr = $"descr", d = $"d", amount = Util.neg (Web.stor ($"amount"))};
152 Money.addHostingCharges {trn = id, cutoff = 1000 * Web.stoi ($"cutoff"), cost = Web.stor ($"cost"), usage = $"usage"};
153
154 %><h3>Hosting transaction modified.</h3>
155
156 <% elseif $"cmd" = "evenForm" then
157 Group.requireGroupName "money";
158 showNormal := false %>
159 <h3>New generic/even transaction</h3>
160 <form action="money" method="post">
161 <input type="hidden" name="cmd" value="even">
162 <table class="blanks">
163 <tr> <td>Description:</td> <td><input name="descr"></td> </tr>
164 <tr> <td>Date:</td> <td><input name="d"></td> </tr>
165 <tr> <td>Amount:</td> <td><input name="amount"></td> </tr>
166 <tr> <td>Members:</td> <td><select name="usrs" size="5" multiple>
167 <% foreach usr in Init.listUsers () do %>
168 <option value="<% #id usr %>"><% #name usr %></option>
169 <% end %>
170 </select></td> </tr>
171 <tr> <td><input type="submit" value="Add"></td> </tr>
172 </table>
173 </form>
174
175 <% elseif $"cmd" = "pay" then
176 Group.requireGroupName "money";
177 val uid = (case $"user" of "" => ~1 | s => Web.stoi s);
178 showNormal := false %>
179
180 <h3>New member payment</h3>
181
182 <form action="money" method="post">
183 <input type="hidden" name="cmd" value="pay2">
184 <table class="blanks">
185 <tr> <td>Description:</td> <td><select name="descr">
186 <option<% if $"checkout" = "" then %> selected<% end %>>PayPal</option>
187 <option<% if $"checkout" <> "" then %> selected<% end %>>Google Checkout</option>
188 <option>Check</option>
189 <option>Direct transfer</option>
190 <option value="">Other:</option>
191 </select> <input name="descr2"></td> </tr>
192 <tr> <td>Date:</td> <td><input name="d" value="<% Web.html (Date.fmt "%B %d, %Y" (Date.fromTimeLocal (Time.now ()))) %>"></td> </tr>
193 <tr> <td>Amount:</td> <td><input name="amount"></td> </tr>
194 <tr> <td>Member:</td> <td><select name="usr">
195 <% foreach usr in Init.listUsers () do %>
196 <option value="<% #id usr %>"<% if #id usr = uid then %> selected<% end %>><% #name usr %></option>
197 <% end %>
198 </select></td> </tr>
199 <tr> <td><input type="submit" value="Add"></td> </tr>
200 </table>
201 </form>
202
203 <% elseif $"cmd" = "pay2" then
204 Group.requireGroupName "money";
205 val amount = Web.stor ($"amount");
206 val descr = $"descr";
207 val descr = iff descr = "" then $"descr2" else descr;
208 val id = Money.addTransaction ($"descr", amount, $"d");
209 Money.addCharge {trn = id, usr = Web.stoi ($"usr"), amount = amount};
210 Money.applyCharges id;
211
212 %><h3>Payment transaction added.</h3>
213
214 <% elseif $"modPay" <> "" then
215 Group.requireGroupName "money";
216 showNormal := false;
217 val id = Web.stoi ($"modPay");
218 val trn = Money.lookupTransaction id %>
219
220 <h3>Modify member payment</h3>
221
222 <form action="money" method="post">
223 <input type="hidden" name="savePay" value="<% id %>">
224 <table class="blanks">
225 <tr> <td>Description:</td> <td><input name="descr" value="<% Web.html (#descr trn) %>"></td> </tr>
226 <tr> <td>Date:</td> <td><input name="d" value="<% Web.html (#d trn) %>"></td> </tr>
227 <tr> <td>Amount:</td> <td><input name="amount" value="<% #amount trn %>"></td> </tr>
228 <tr> <td>Member:</td> <td><select name="usr">
229 <% foreach (sel, usr) in Money.listUsers (#id trn) do %>
230 <option value="<% #id usr %>"<% if sel then %> selected<% end %>><% #name usr %></option>
231 <% end %>
232 </td></tr>
233 <tr> <td><input type="submit" value="Save"></td> </tr>
234 </table>
235
236 <% elseif $"savePay" <> "" then
237 Group.requireGroupName "money";
238 val id = Web.stoi ($"savePay");
239 val trn = Money.lookupTransaction id;
240
241 val amount = Web.stor ($"amount");
242 Money.clearCharges id;
243 Money.modTransaction {trn with descr = $"descr", d = $"d", amount = amount};
244 Money.addCharge {trn = id, usr = Web.stoi ($"usr"), amount = amount};
245 Money.applyCharges id;
246
247 %><h3>Member payment modified.</h3>
248
249 <% elseif $"cmd" = "evenForm" then
250 Group.requireGroupName "money";
251 showNormal := false %>
252 <h3>New generic/even transaction</h3>
253 <form action="money" method="post">
254 <input type="hidden" name="cmd" value="even">
255 <table class="blanks">
256 <tr> <td>Description:</td> <td><input name="descr"></td> </tr>
257 <tr> <td>Date:</td> <td><input name="d"></td> </tr>
258 <tr> <td>Amount:</td> <td><input name="amount"></td> </tr>
259 <tr> <td>Members:</td> <td><select name="usrs" size="5" multiple>
260 <% foreach usr in Init.listUsers () do %>
261 <option value="<% #id usr %>"><% #name usr %></option>
262 <% end %>
263 </select></td> </tr>
264 <tr> <td><input type="submit" value="Add"></td> </tr>
265 </table>
266 </form>
267
268 <% elseif $"cmd" = "even" then
269 Group.requireGroupName "money";
270 val id = Money.addTransaction ($"descr", Web.stor ($"amount"), $"d");
271 Money.addEvenCharges (id, map Web.stoi (Web.getMultiParam "usrs"))
272
273 %><h3>Even transaction added.</h3>
274
275 <% elseif $"modEven" <> "" then
276 Group.requireGroupName "money";
277 showNormal := false;
278 val trn = Money.lookupTransaction (Web.stoi ($"modEven")) %>
279 <h3>Modify even transaction</h3>
280
281 <form action="money" method="post">
282 <input type="hidden" name="saveEven" value="<% $"modEven" %>">
283 <table class="blanks">
284 <tr> <td>Description:</td> <td><input name="descr" value="<% Web.html (#descr trn) %>"></td> </tr>
285 <tr> <td>Date:</td> <td><input name="d" value="<% Web.html (#d trn) %>"></td> </tr>
286 <tr> <td>Amount:</td> <td><input name="amount" value="<% #amount trn %>"></td> </tr>
287 <tr> <td>Members:</td> <td><select name="usrs" size="5" multiple>
288 <% foreach (sel, usr) in Money.listUsers (#id trn) do %>
289 <option value="<% #id usr %>"<% if sel then %> selected<% end %>><% #name usr %></option>
290 <% end %>
291 </select></td> </tr>
292 <tr> <td><input type="submit" value="Save"></td> </tr>
293 </table>
294 </form>
295
296 <% elseif $"saveEven" <> "" then
297 Group.requireGroupName "money";
298 val id = Web.stoi ($"saveEven");
299 val trn = Money.lookupTransaction id;
300 Money.clearCharges id;
301 Money.modTransaction {trn with descr = $"descr", d = $"d", amount = Web.stor ($"amount")};
302 Money.addEvenCharges (id, map Web.stoi (Web.getMultiParam "usrs"))
303
304 %><h3>Even transaction modified</h3>
305
306 <% elseif $"del" <> "" then
307 Group.requireGroupName "money";
308 showNormal := false;
309 val trn = Money.lookupTransaction (Web.stoi ($"del")) %>
310 <h3>Are you sure you want to delete transaction <a href="money?trn=<% #id trn %>"><% Web.html (#descr trn) %></a>?</h3>
311 <a href="money?del2=<% $"del" %>">Yes, delete <% Web.html (#descr trn) %>!</a>
312
313 <% elseif $"del2" <> "" then
314 Group.requireGroupName "money";
315 val id = Web.stoi ($"del2");
316 val trn = Money.lookupTransaction id;
317 Money.clearCharges id;
318 Money.deleteTransaction id %>
319 <h3><% Web.html (#descr trn) %> deleted!</h3>
320
321 <% elseif $"cmd" = "equalize" then
322 Group.requireGroupName "money";
323 Money.equalizeBalances ();
324 %><h3>Balances equalized</h3>
325
326 <% elseif $"trn" <> "" then
327 showNormal := false;
328 val id = Web.stoi ($"trn");
329 val trn = Money.lookupTransaction id %>
330 <table class="blanks">
331 <tr> <td>TRN#:</td> <td><% id %></td> </tr>
332 <tr> <td>Description:</td> <td><% Web.html (#descr trn) %></td> </tr>
333 <tr> <td>Date:</td> <td><% #d trn %></td> </tr>
334 <tr> <td>Amount:</td> <td>$<% #amount trn %></td> </tr>
335 <tr> <td>Distribution:</td>
336
337 <% ref first = true;
338 foreach (name, cha) in Money.listChargesWithNames id do
339 if first then
340 first := false
341 else
342 %><tr> <td></td> <%
343 end
344 %><td><a href="user?id=<% #usr cha %>"><% name %></a></td> <td>$<% #amount cha %></td> </tr><%
345 end %>
346 </table>
347
348 <% elseif $"cmd" = "paypal" then
349 showNormal := false;
350 val apps = App.searchPaypal ($"email");
351 val users = Init.searchPaypal ($"email");
352
353 switch apps of
354 _ :: _ =>
355 %><h3>Approved applications</h3>
356
357 <% foreach appl in apps do %>
358 <br><hr><br>
359 <table class="blanks">
360 <tr> <td>Received:</td> <td><% #applied appl %></td> </tr>
361 <tr> <td>Approved by:</td> <td><%
362 ref first = true;
363 ref found = false;
364 foreach (id, name) in App.votes (#id appl) do
365 if first then
366 first := false
367 else
368 %>, <%
369 end
370 %><a href="user?id=<% id %>"><% name %></a><%
371 end %> </td> </tr>
372 <tr> <td>Username:</td> <td><% #name appl %></td> </tr>
373 <tr> <td>Real name:</td> <td><% Web.html (#rname appl) %></td> </tr>
374 <tr> <td>E-mail address:</td> <td><a href="mailto:<% #email appl %>"><% #email appl %></a></td> </tr>
375 <% switch #paypal appl of
376 SOME s => %><tr> <td>PayPal:</td> <td><a href="mailto:<% s %>"><% s %></a></td> </tr>
377 <% end;
378 switch #checkout appl of
379 SOME s => %><tr> <td>Google Checkout:</td> <td><a href="mailto:<% s %>"><% s %></a></td> </tr>
380 <% end %>
381 <tr> <td>Forward e-mail?</td> <td><% if #forward appl then %>yes<% else %>no<% end %></td> </tr>
382 <tr> <td>Proposed uses:</td> <td><% Web.htmlNl (#uses appl) %></td> </tr>
383 <tr> <td>Other information:</td> <td><% Web.htmlNl (#other appl) %></td> </tr>
384 </table>
385
386 <% if root then %>
387 <a href="apps?add=<% #id appl %>">Add this member.</a><br>
388 <% end
389 end
390 end;
391
392 switch users of
393 _ :: _ =>
394 %><h3>Members</h3>
395
396 <% foreach user in users do %>
397 <li> <a href="user?id=<% #id user %>"><% #name user %></a> <a href="?cmd=pay&user=<% #id user %>">[add payment]</a></li>
398 <% end
399 end;
400
401 switch (apps, users) of
402 (nil, nil) => %>No matches.<%
403 end
404
405 elseif $"cmd" = "checkout" then
406 showNormal := false;
407 val apps = App.searchCheckout ($"email");
408 val users = Init.searchCheckout ($"email");
409
410 switch apps of
411 _ :: _ =>
412 %><h3>Approved applications</h3>
413
414 <% foreach appl in apps do %>
415 <br><hr><br>
416 <table class="blanks">
417 <tr> <td>Received:</td> <td><% #applied appl %></td> </tr>
418 <tr> <td>Approved by:</td> <td><%
419 ref first = true;
420 ref found = false;
421 foreach (id, name) in App.votes (#id appl) do
422 if first then
423 first := false
424 else
425 %>, <%
426 end
427 %><a href="user?id=<% id %>"><% name %></a><%
428 end %> </td> </tr>
429 <tr> <td>Username:</td> <td><% #name appl %></td> </tr>
430 <tr> <td>Real name:</td> <td><% Web.html (#rname appl) %></td> </tr>
431 <tr> <td>E-mail address:</td> <td><a href="mailto:<% #email appl %>"><% #email appl %></a></td> </tr>
432 <% switch #paypal appl of
433 SOME s => %><tr> <td>PayPal:</td> <td><a href="mailto:<% s %>"><% s %></a></td> </tr>
434 <% end;
435 switch #checkout appl of
436 SOME s => %><tr> <td>Google Checkout:</td> <td><a href="mailto:<% s %>"><% s %></a></td> </tr>
437 <% end %>
438 <tr> <td>Forward e-mail?</td> <td><% if #forward appl then %>yes<% else %>no<% end %></td> </tr>
439 <tr> <td>Proposed uses:</td> <td><% Web.htmlNl (#uses appl) %></td> </tr>
440 <tr> <td>Other information:</td> <td><% Web.htmlNl (#other appl) %></td> </tr>
441 </table>
442
443 <% if root then %>
444 <a href="apps?add=<% #id appl %>">Add this member.</a><br>
445 <% end
446 end
447 end;
448
449 switch users of
450 _ :: _ =>
451 %><h3>Members</h3>
452
453 <% foreach user in users do %>
454 <li> <a href="user?id=<% #id user %>"><% #name user %></a> <a href="?cmd=pay&user=<% #id user %>&checkout=1">[add payment]</a></li>
455 <% end
456 end;
457
458 switch (apps, users) of
459 (nil, nil) => %>No matches.<%
460 end
461
462 end %>
463
464 <% if showNormal then %>
465
466 <h3>Your balance: $<% #amount (Balance.lookupBalance (#bal (Init.getUser ()))) %></h3>
467 <% if (iff Group.inGroupName "money" then $"lookback" = "" else $"audit" <> "") then %><h3>Sum of all active balances: $<% Balance.sumOwnedBalances () %></h3><% end %>
468
469 <a href="money?cmd=list">List all transactions</a><br>
470 <a href="money?cmd=bals">List active balances</a><br>
471 <a href="money?cmd=nbals">List negative active balances</a><br>
472 <a href="money?cmd=deadbals">List retired balances</a><br>
473
474 <% if (Group.inGroupName "money" and $"lookback" = "") or $"audit" <> "" then %>
475
476 <a href="?lookback=20">Switch to regular member view</a><br>
477
478 <br><b><u>New transaction:</u></b><br>
479 <a href="money?cmd=hosting">Hosting bill</a><br>
480 <a href="money?cmd=pay">Payment from member</a><br>
481 <a href="money?cmd=evenForm">Generic/even</a><br>
482 <br>
483 <a href="money?cmd=equalize">Equalize balances</a><br>
484 <br>
485
486 <h3>Look up a PayPal e-mail address</h3>
487
488 <form method="post">
489 <input type="hidden" name="cmd" value="paypal">
490 <input name="email"> <input type="submit" value="Look up">
491 </form>
492
493 <h3>Look up a Google Checkout e-mail address</h3>
494
495 <form method="post">
496 <input type="hidden" name="cmd" value="checkout">
497 <input name="email"> <input type="submit" value="Look up">
498 </form>
499
500 <h3>Most recent transactions</h3>
501
502 <table>
503 <tr> <td><b>Date</b></td> <td><b>Description</b></td> <td><b>Amount</b></td> <td><b>Participants</b></td> <td><b>Replace</b></td> <td><b>Delete</b></td> </tr>
504 <% foreach trn in Money.listTransactionsLimit 20 do %>
505 <tr> <td><% #d trn %></td> <td><a href="money?trn=<% #id trn %>"><% Web.html (#descr trn) %></a></td> <td><% #amount trn %></td>
506 <% switch Money.listChargesWithNames (#id trn) of
507 [(name, cha)] => %><td><a href="user?id=<% #usr cha %>"><% name %></a></td><%
508 | _ => %><td><i>multi</i></td><%
509 end %>
510 <td><a href="money?modHosting=<% #id trn %>">[Hosting]</a> <a href="money?modPay=<% #id trn %>">[Payment]</a> <a href="money?modEven=<% #id trn %>">[Other]</a></td>
511 <td><a href="money?del=<% #id trn %>">[Delete]</a></td> </tr>
512 <% end %>
513 </table>
514
515 <% else %>
516 <a href="?audit=1">Switch to audit view</a><br>
517 <% val lookback = case $"lookback" of "" => 20 | lb => Web.stoi lb;
518 @payment [] %>
519
520 <h3>Your recent account activity</h3>
521
522 <form>
523 Show <input name="lookback" size="5" value="<% lookback %>"> most recent transactions.
524 <input type="submit" value="Show">
525 </form>
526
527 <table>
528 <tr> <td><b>Date</b></td> <td><b>Description</b></td> <td><b>Amount</b></td> </tr>
529 <% foreach (amount, trn) in Money.listUserTransactionsLimit (Init.getUserId (), lookback) do %>
530 <tr> <td><% #d trn %></td> <td><a href="money?trn=<% #id trn %>"><% Web.html (#descr trn) %></a></td> <td><% amount %>/<% #amount trn %></td> </tr>
531 <% end %>
532 </table>
533
534 <% end
535 end %>
536
537 <% @footer [] %>