5156f274d342f09c934c17d3b4d3d8a2abd0129b
[memberdb.git] / include / payments.php
1 <?php
2
3 // NOTE: combination of earnings and expenses
4
5 $ACCOUNT_TYPES = array(
6     'bank' => 'Konto',
7     'cash' => 'Kasse'
8 );
9
10 /* DB functions {{{ */
11 function db_get_payments($offset, $count, $where)
12 {
13     $limit = '';
14     if (isset($offset) && isset($count)) {
15         $limit = sprintf(' LIMIT %d,%d', (int)$offset, (int)$count);
16     } elseif (isset($offset)) {
17         $limit = sprintf(' LIMIT %d', (int)$count);
18     }
19     $sql = "
20         SELECT t.*, members.nickname AS nickname
21         FROM (
22             (SELECT 'earning' AS ptype, `earnings`.* FROM `earnings` `earnings`)
23             UNION
24             (SELECT 'expense', expenses.* FROM `expenses` `earnings`)
25         ) AS t
26         LEFT JOIN `members` ON t.member_id=members.id
27         ORDER BY `date` DESC, t.id DESC
28     " . $limit;
29     return db_select_multi(sprintf($sql, $where));
30 }
31
32 function db_get_finished_payments($offset, $count)
33 {
34     $where = " WHERE status='paid'";
35     $payments = db_get_payments($offset, $count, $where);
36
37     $bank = 0;
38     $cash = 0;
39     $total = 0;
40     if ($count != 0) { // XXX TODO hä? - An dieser Stelle gäbe es sinnigere Bedinungen
41         $limit = sprintf(' LIMIT %d,18446744073709551615',
42             (int)($count + $offset)); // SELECT mit Offset aber ohne Limit
43         $sql = "SELECT SUM(IF(`account`='bank', `value`, 0)) AS `bank`, SUM(IF(`account`='cash', `value`, 0)) AS `cash`, SUM(`value`) AS `total` 
44                 FROM (
45                     SELECT `value`, `account` 
46                     FROM (( SELECT `value`,                 `id`, `date`, `account` FROM `earnings` %1\$s) 
47                     UNION ( SELECT `value` * -1 AS `value`, `id`, `date`, `account` FROM `expenses` %1\$s)
48                     ) AS t
49                     ORDER BY `date` DESC, t.id DESC" . $limit . '
50                 ) AS u';
51         $row = db_select_single(sprintf($sql, $where));
52         $bank = $row['bank'];
53         $cash = $row['cash'];
54         $total = $row['total'];
55     }
56     for ($i = count($payments) - 1; $i >= 0; $i--) {
57         $value = $payments[$i]['value'];
58         if ($payments[$i]['ptype'] == 'expense') {
59             $value = bcmul($value, '-1');
60         }
61         switch ($payments[$i]['account']) {
62             case 'bank':
63                 $bank = bcadd($bank, $value);
64                 break;
65             case 'cash':
66                 $cash = bcadd($cash, $value);
67                 break;
68             default:
69                 break; // TODO XXX die?
70         }
71         $total = bcadd($total, $value);
72         $payments[$i]['bank'] = $bank;
73         $payments[$i]['cash'] = $cash;
74         $payments[$i]['total'] = $total;
75     }
76     return $payments;
77 }
78
79 function db_count_finished_payments()
80 {
81     $where = " WHERE status='paid'";
82     $sql = 'SELECT count(*) AS `count` FROM ((SELECT * FROM `earnings` %1$s) UNION (SELECT * FROM `expenses` %1$s)) AS t';
83     $row = db_select_single(sprintf($sql, $where));
84     return $row['count'];
85 }
86
87 function db_get_open_payments($offset, $count)
88 {
89     return db_get_payments($offset, $count, " WHERE status='open'");
90 }
91
92 /* }}} */
93
94 function render_finished_payments($count = 100)
95 {/*{{{*/
96     global $EXPENSE_TYPES, $EARNING_TYPES, $ACCOUNT_TYPES;
97     $page = 1;
98     if (!empty($_REQUEST['page'])) {
99         $page = max(1, (int)$_REQUEST['page']);
100     }
101     $payments = db_get_finished_payments(($page - 1) * $count, $count);
102     $max = db_count_finished_payments();
103     ?>
104     <h3 id="finished">Abgeschlossene Zahlungen</h3>
105     <?php if (isset($payments)) : ?>
106     <table>
107         <tr>
108             <th>Id</th>
109             <th>Datum</th>
110             <th>Typ</th>
111             <th>Mitglied</th>
112             <th>Betrag</th>
113             <th>Beschreibung</th>
114             <th>Konto</th>
115             <th>Kasse</th>
116             <th>Gesamt</th>
117         </tr>
118         <?php foreach ($payments as $payment) : ?>
119             <tr class="<?= $payment['ptype'] ?>">
120                 <td style="text-align: right;"><a href="<?= html_escape(link_to('change_' . $payment['ptype'],
121                         array('id' => $payment['id']))) ?>"><?= html_escape($payment['id']) ?></a></td>
122                 <td><?= html_escape(format_date(db_date2unixtime($payment['date']))) ?></td>
123                 <td><?= html_escape($payment['ptype'] == 'earning' ? $EARNING_TYPES[$payment['type']] : $EXPENSE_TYPES[$payment['type']]) ?></td>
124                 <td><?php if ($payment['member_id'] != 0) : ?><a href="<?= html_escape(link_to('view_member',
125                         array('id' => $payment['member_id']))) ?>"><?= html_escape($payment['nickname']) ?><?php endif ?></a>
126                 </td>
127                 <td style="text-align: right;"><?= html_escape(format_money(($payment['ptype'] == 'earning' ? 1 : -1) * $payment['value'])) ?></td>
128                 <td><?= html_escape($payment['description']) ?></td>
129                 <td style="text-align: right;<?php if ($payment['account'] == 'bank') : ?> text-decoration:underline;<?php endif ?>"><?= html_escape(format_money($payment['bank'])) ?></td>
130                 <td style="text-align: right;<?php if ($payment['account'] == 'cash') : ?> text-decoration:underline;<?php endif ?>"><?= html_escape(format_money($payment['cash'])) ?></td>
131                 <td style="text-align: right;"><?= html_escape(format_money($payment['total'])) ?></td>
132             </tr>
133         <?php endforeach ?>
134     </table>
135     <?php paginate(link_to('finances') . '&page=%d#finished', $page, ceil($max / $count)); ?>
136 <?php else : ?>
137     <p>Bisher gibt's noch keine abgeschlossenen Zahlungen.</p>
138 <?php endif ?>
139     <?php
140
141 }/*}}}*/
142
143 function render_open_payments($offset = 0, $count = 25)
144 {/*{{{*/
145     global $EXPENSE_TYPES, $EARNING_TYPES, $ACCOUNT_TYPES;
146     global $EXPENSE_TYPES, $EARNING_TYPES;
147     $payments = db_get_open_payments($offset, $count);
148     ?>
149     <h3>Offene Zahlungen</h3>
150     <?php if (isset($payments)) : ?>
151     <table>
152         <tr>
153             <th>Id</th>
154             <th>Datum</th>
155             <th>Typ</th>
156             <th>Mitglied</th>
157             <th>Quelle/Ziel</th>
158             <th>Betrag</th>
159             <th>Beschreibung</th>
160         </tr>
161         <?php foreach ($payments as $payment) : ?>
162             <tr class="<?= $payment['ptype'] ?>">
163                 <td style="text-align: right;"><a href="<?= html_escape(link_to('change_' . $payment['ptype'],
164                         array('id' => $payment['id']))) ?>"><?= html_escape($payment['id']) ?></a></td>
165                 <td><?= html_escape(format_date(db_date2unixtime($payment['date']))) ?></td>
166                 <td><?= html_escape($payment['ptype'] == 'earning' ? $EARNING_TYPES[$payment['type']] : $EXPENSE_TYPES[$payment['type']]) ?></td>
167                 <td><?php if ($payment['member_id'] != 0) : ?><a href="<?= html_escape(link_to('view_member',
168                         array('id' => $payment['member_id']))) ?>"><?= html_escape($payment['nickname']) ?><?php endif ?></a>
169                 </td>
170                 <td><?= html_escape($ACCOUNT_TYPES[$payment['account']]) ?></td>
171                 <td style="text-align: right;"><?= html_escape(format_money(($payment['ptype'] == 'earning' ? 1 : -1) * $payment['value'])) ?></td>
172                 <td><?= html_escape($payment['description']) ?></td>
173             </tr>
174         <?php endforeach ?>
175     </table>
176 <?php else : ?>
177     <p>Bisher gibt's noch keine abgeschlossenen Zahlungen.</p>
178 <?php endif ?>
179     <?php
180
181 }/*}}}*/