Fixed typos…
[memberdb.git] / include / directdebit.php
1 <?php
2
3
4 function action_directdebit() {
5
6     $debittype = array(
7         1 => 'DTAUS',
8         2 => 'FRST',
9         3 => 'RCUR'
10     ); 
11
12     $members = db_get_members();
13     if (empty($members)) return;
14
15     $debits = array();
16     $cash_payments = array();
17     foreach ($members as $member) {
18                 if (empty($member['directdebit'])) {
19                         // Barzahler
20                         $open = bcsub(fees_sum_for_member($member['id'], time()), bcadd(finance_get_paid_fees_for_member($member['id']), finance_get_paid_fees_for_member($member['id'], true)));
21                         if (bccomp($open, 0) != 1) continue;
22                         $cash_payments[] = array(
23                                 'member_id'     => $member['id'],
24                                 'member_number' => $member['number'],
25                                 'nickname'      => $member['nickname'],
26                                 'amount'        => $open
27                         );
28                         continue;
29                 }
30         foreach(fee_next_directdebit_for_member($member['id'], time()) as $info) {
31             if (empty($info)) continue;
32             $debits[] = array(
33                 'member_id'        => $member['id'],
34                 'member_number'    => $member['number'],
35                 'nickname'         => $member['nickname'],
36                 'accountholder'    => $member['accountholder'],
37                 'accountnumber'    => $member['accountnumber'],
38                 'bankcode'         => $member['bankcode'],
39 //              'bankname'         => $member['bankname'],
40                 'amount'           => $info['value'],
41                 'amountcent'       => '' . (int)round(bcmul($info['value'], 100)),
42                 'purpose'          => $info['info'],
43                 'ddmandatesigdate' => $member['ddmandatesigdate'],
44                 'debittype'        => $debittype[$member['directdebit']],
45             );
46         }
47     }
48
49     js_modal_windows();
50     js_get_master_key();
51
52 ?>
53     <noscript>
54         <p class="error">
55             <strong>Achtung:</strong> Ohne JavaScript geht hier gar nichts. Bitte aktivieren!
56         </p>
57     </noscript>
58 <?php if (!empty($cash_payments)) : ?>
59 <h2>Barzahler</h2>
60 <table>
61     <tr>
62         <th>Mitgliedsnummer</th>
63         <th>Nickname</th>
64         <th style="text-align: right;">Betrag</th>
65                 <th></th>
66         </tr>
67 <?php foreach ($cash_payments as $payment) : ?>
68     <tr>
69         <td><a href="<?=html_escape(link_to('fees', array('member_id'=> $payment['member_id'])))?>"><?=html_escape($payment['member_number'])?></a></td>
70         <td><?=html_escape($payment['nickname'])?></td>
71         <td style="text-align: right;"><?=html_escape(format_money($payment['amount']))?></td>
72                 <td>
73                         <form action="<?=link_to('create_earning')?>" method="post" class="clearfix">
74                                 <?=html_hidden_field('date', format_date(time()))?>
75                                 <?=html_hidden_field('type', 'fee')?>
76                                 <?=html_hidden_field('status', 'paid')?>
77                                 <?=html_hidden_field('value', format_money($payment['amount']))?>
78                                 <?=html_hidden_field('member_id', $payment['member_id'])?>
79                                 <?=html_hidden_field('description', '')?>
80                                 <?=html_hidden_field('account', 'cash')?>
81                                 <input class="submit" type="submit" name="submit" value="Einnahme verbuchen"/>
82                         </form>
83                 </td>
84     </tr>
85 <?php endforeach ?>
86 </table>
87 <?php endif ?>
88
89 <h2>Bankeinzug</h2>
90 <table>
91     <tr>
92         <th>Mitgliedsnummer</th>
93         <th>Nickname</th>
94         <th>Verwendungszweck</th>
95         <th>Einzugstyp</th>
96         <th style="text-align: right;">Betrag</th>
97     </tr>
98 <?php $total = 0; ?>
99 <?php foreach ($debits as $debit) : ?>
100     <tr>
101         <td><a href="<?=html_escape(link_to('fees', array('member_id'=> $debit['member_id'])))?>"><?=html_escape($debit['member_number'])?></a></td>
102         <td><?=html_escape($debit['nickname'])?></td>
103         <td><?=html_escape($debit['purpose'])?></td>
104         <td><?=html_escape($debit['debittype'])?></td>
105         <td style="text-align: right;"><?=html_escape(format_money($debit['amount']))?></td>
106     </tr>
107     <?php $total = bcadd($total, $debit['amount']); ?>
108 <?php endforeach ?>
109     <tr class="total">
110         <td>Gesamt</td>
111         <td></td>
112         <td></td>
113         <td></td>
114         <td style="text-align: right;"><?=html_escape(format_money($total))?></td>
115     </tr>
116 </table>
117
118 <!-- ?=html_hidden_field('directdebittype', 'pain')? -->
119 <?=html_list_box('Dateiformat', 'directdebittype', array('dtaus' => 'DTAUS', 'pain' => 'PAIN'), 'pain');?>
120 <input class="submit" type="button" name="btn_directdebit" value="Datei erzeugen" onclick="ask_for_password()" id="btn_directdebit"/>
121 <br/>
122 <br/>
123 <form action="<?=link_to('create_earnings')?>" method="post" class="clearfix">
124 <?php $count = 0; ?>
125 <?php foreach ($debits as $debit) : ?>
126     <?=html_hidden_field(sprintf('earnings[%d][date]',        $count), strftime(DIRECTDEBIT_DAY_OF_MONTH . '.%m.%Y', time()) )?>
127     <?=html_hidden_field(sprintf('earnings[%d][type]',        $count), 'fee')?>
128     <?=html_hidden_field(sprintf('earnings[%d][status]',      $count), 'paid')?>
129     <?=html_hidden_field(sprintf('earnings[%d][value]',       $count), $debit['amount'])?>
130     <?=html_hidden_field(sprintf('earnings[%d][member_id]',   $count), $debit['member_id'])?>
131     <?=html_hidden_field(sprintf('earnings[%d][description]', $count), $debit['purpose'])?>
132     <?php $count++; ?>
133 <?php endforeach ?>
134 <input class="submit" type="submit" name="btn_create_earnings" value="Einnahmen verbuchen"/>
135 </form>
136 <hr/>
137 <form action="<?=link_to('export_ibanhin')?>" method="POST" class="clearfix">
138 <input class="submit" type="submit" name="btn_export_ibanhin" value="IBAN-hin Export"/>
139 </form>
140
141 <div id="password_popup" class="modal_window">
142     <fieldset>
143         <legend>Passwortabfrage</legend>
144         <?=html_password_field('Passwort', 'password')?>
145         <input class="submit" type="button" name="btn_generate_directdebit" value="Datei erzeugen" onclick="generate_directdebit()"/>
146         <input class="submit" type="button" name="btn_cancel" value="Abbrechen" onclick="cancel_ask_for_password()"/>
147     </fieldset>
148 </div>
149 <div id="directdebit_popup" class="modal_window">
150     <fieldset>
151         <legend>DTAUS / SEPA PAIN FRST</legend>
152             <textarea id="directdebit_content" style="width: 100%" rows="15" readonly="readonly"></textarea>
153         <legend>SEPA PAIN RCUR</legend>
154             <textarea id="directdebit_content2" style="width: 100%" rows="15" readonly="readonly"></textarea>
155             <input class="submit" type="button" name="btn_directdebit_close" value="Schließen" onclick="directdebit_close()"/>
156     </fieldset>
157 </div>
158
159 <script type="text/javascript">
160
161 var debits = new Array(
162     <?=join(",\n", array_map('json_encode', $debits)) ?>
163 );
164
165
166 $(document).ready(function(){  
167     $('#password').keypress( function(event) { if (event.keyCode == '13') { generate_directdebit(); } });
168     $('#btn_directdebit').focus();
169 });  
170
171
172 function ask_for_password() {/*{{{*/
173     modal_window_show($("#password_popup"));
174     $("#password").focus();
175     return;
176 }/*}}}*/
177
178 function cancel_ask_for_password() {/*{{{*/
179     modal_window_hide();
180     $("#btn_directdebit").focus();
181     return;
182 }/*}}}*/
183
184
185 function generate_directdebit() {/*{{{*/
186
187     var password = $('#password').val();
188     var directdebitcontent = "";
189     var directdebitcontent2 = "Wird nur bei SEPA verwendet.";
190     $("#password").val('');
191
192     // We pass a closure so that get_master_key may defer execution
193     get_master_key(password, function(masterkey) {
194
195         modal_window_replace($("#directdebit_popup"));
196
197     switch ($('#directdebittype').val()) {
198         case "dtaus":
199             if (!DTAUS.setAccountFileSender('<?=dtaus_string(ACCOUNT_HOLDER)?>', '<?=BANK_CODE?>', '<?=ACCOUNT_NUMBER?>')) {
200                 $('#directdebit_content').val(DTAUS.errormsg);
201                 return;
202             }
203
204             for (var i = 0; i < debits.length; i++) {
205             
206                 if (debits[i]['debittype'] != 'DTAUS' ) {
207                   continue;
208                 }
209                 
210                 var accountholder = debits[i]['accountholder'];
211                 var accountnumber = debits[i]['accountnumber'];
212                 var bankcode      = debits[i]['bankcode'];
213
214                 // Encrypt/Decrypt data using AES with masterkey
215                 if (accountholder != "") accountholder = Crypto.charenc.UTF8.bytesToString(Crypto.AES.decrypt(accountholder, masterkey));
216                 if (accountnumber != "") accountnumber = Crypto.charenc.UTF8.bytesToString(Crypto.AES.decrypt(accountnumber, masterkey));
217                 if (bankcode      != "") bankcode      = Crypto.charenc.UTF8.bytesToString(Crypto.AES.decrypt(bankcode,      masterkey));
218
219                 accountholder = DTAUS.prepareString(accountholder);
220
221                 if (!DTAUS.addExchange(accountholder, bankcode, accountnumber, '', debits[i]['amountcent'], debits[i]['purpose'])) {
222                     $('#directdebit_content').val('Mitglied ' + debits[i]['member_number'] + ' ' + accountholder + '\n' + DTAUS.errormsg);
223                     return;
224                 }
225             }
226             directdebitcontent = DTAUS.getFileContent();
227             break;
228             
229         case "pain":
230
231             <?php $bic = (USE_BIC == 1)?'\''.BIC.'\'':'null'; ?>    
232             
233             // datejs.com MAGIC
234             var jetzt = new Date.today();
235             var collectiondate = new Date.parse('<?=DIRECTDEBIT_DAY_OF_MONTH?>');
236             if (jetzt.getDate() > <?=DIRECTDEBIT_DAY_OF_MONTH?>) {
237               collectiondate = collectiondate.add(1).month();
238             }
239
240             if (!SEPACORE.init(collectiondate, '<?=CREDITOR_IDENTIFIER?>', '<?=ACCOUNT_HOLDER?>', '<?=IBAN?>', <?=$bic?>)) {
241                 $('#directdebit_content').val(DTAUS.errormsg);
242                 return;
243             }
244
245             for (var i = 0; i < debits.length; i++) {
246             
247                 if (debits[i]['debittype'] != 'FRST' && debits[i]['debittype'] != 'RCUR' ) {
248                   continue;
249                 }
250                 
251                 var accountholder = debits[i]['accountholder'];
252                 var accountnumber = debits[i]['accountnumber'];
253                 var bankcode      = debits[i]['bankcode'];
254
255                 // Encrypt/Decrypt data using AES with masterkey
256                 if (accountholder != "") accountholder = Crypto.charenc.UTF8.bytesToString(Crypto.AES.decrypt(accountholder, masterkey));
257                 if (accountnumber != "") accountnumber = Crypto.charenc.UTF8.bytesToString(Crypto.AES.decrypt(accountnumber, masterkey));
258                 if (bankcode      != "") bankcode      = Crypto.charenc.UTF8.bytesToString(Crypto.AES.decrypt(bankcode,      masterkey));
259                 
260                 // Mandatsreferenz '/V1/M:n/'; z.B. /V:1/M:2/
261                 var mandateref = '/V:1/M:' + debits[i]['member_number'] + '/';
262                 var e2eid = '/V:1/E2E:' + parseInt(SEPACORE.creationdate.getTime()/1000) + '/S:' + debits[i]['debittype'][0] + '/I:' + i + '/';
263                 if (!SEPACORE.addDDTx(debits[i]['debittype'], accountholder, accountnumber, bankcode, mandateref, debits[i]['ddmandatesigdate'].substring(0, 10), debits[i]['amountcent'], debits[i]['purpose'], e2eid)) {
264                     $('#directdebit_content').val('Mitglied ' + debits[i]['member_number'] + ' ' + accountholder + '\n' + SEPACORE.errormsg);
265                     return;
266                 }
267             }
268             
269             directdebitcontent = SEPACORE.getXMLContent('FRST');
270             directdebitcontent2 = SEPACORE.getXMLContent('RCUR');
271             
272             if (SEPACORE.errormsg.lenght > 0) {
273                 $('#directdebit_content').val(SEPACORE.errormsg);
274                 return;
275             }
276             break;
277         }
278         $('#directdebit_content').val(directdebitcontent);
279         $('#directdebit_content2').val(directdebitcontent2);
280         $('#directdebit_content').focus();
281         $('#directdebit_content').select();
282     });
283
284 }/*}}}*/
285
286 function directdebit_close() {/*{{{*/
287     modal_window_hide();
288     $("#directdebit_content").val('');
289     $("#directdebit_content2").val('');
290 }/*}}}*/
291
292
293
294 </script>
295 <?php
296 }
297
298 // borrowed from PEARs Payment_DTA
299 function dtaus_string($string) {
300     if (strlen($string) == 0) return '';
301     $special_chars = array(
302         'á' => 'a',
303         'à' => 'a',
304         'ä' => 'ae',
305         'â' => 'a',
306         'ã' => 'a',
307         'å' => 'a',
308         'æ' => 'ae',
309         'ā' => 'a',
310         'ă' => 'a',
311         'ą' => 'a',
312         'ȁ' => 'a',
313         'ȃ' => 'a',
314         'Á' => 'A',
315         'À' => 'A',
316         'Ä' => 'Ae',
317         'Â' => 'A',
318         'Ã' => 'A',
319         'Å' => 'A',
320         'Æ' => 'AE',
321         'Ā' => 'A',
322         'Ă' => 'A',
323         'Ą' => 'A',
324         'Ȁ' => 'A',
325         'Ȃ' => 'A',
326         'ç' => 'c',
327         'ć' => 'c',
328         'ĉ' => 'c',
329         'ċ' => 'c',
330         'č' => 'c',
331         'Ç' => 'C',
332         'Ć' => 'C',
333         'Ĉ' => 'C',
334         'Ċ' => 'C',
335         'Č' => 'C',
336         'ď' => 'd',
337         'đ' => 'd',
338         'Ď' => 'D',
339         'Đ' => 'D',
340         'é' => 'e',
341         'è' => 'e',
342         'ê' => 'e',
343         'ë' => 'e',
344         'ē' => 'e',
345         'ĕ' => 'e',
346         'ė' => 'e',
347         'ę' => 'e',
348         'ě' => 'e',
349         'ȅ' => 'e',
350         'ȇ' => 'e',
351         'É' => 'E',
352         'È' => 'E',
353         'Ê' => 'E',
354         'Ë' => 'E',
355         'Ē' => 'E',
356         'Ĕ' => 'E',
357         'Ė' => 'E',
358         'Ę' => 'E',
359         'Ě' => 'E',
360         'Ȅ' => 'E',
361         'Ȇ' => 'E',
362         'ĝ' => 'g',
363         'ğ' => 'g',
364         'ġ' => 'g',
365         'ģ' => 'g',
366         'Ĝ' => 'G',
367         'Ğ' => 'G',
368         'Ġ' => 'G',
369         'Ģ' => 'G',
370         'ĥ' => 'h',
371         'ħ' => 'h',
372         'Ĥ' => 'H',
373         'Ħ' => 'H',
374         'ì' => 'i',
375         'ì' => 'i',
376         'î' => 'i',
377         'ï' => 'i',
378         'ĩ' => 'i',
379         'ī' => 'i',
380         'ĭ' => 'i',
381         'į' => 'i',
382         'ı' => 'i',
383         'ij' => 'ij',
384         'ȉ' => 'i',
385         'ȋ' => 'i',
386         'Í' => 'I',
387         'Ì' => 'I',
388         'Î' => 'I',
389         'Ï' => 'I',
390         'Ĩ' => 'I',
391         'Ī' => 'I',
392         'Ĭ' => 'I',
393         'Į' => 'I',
394         'İ' => 'I',
395         'IJ' => 'IJ',
396         'Ȉ' => 'I',
397         'Ȋ' => 'I',
398         'ĵ' => 'j',
399         'Ĵ' => 'J',
400         'ķ' => 'k',
401         'Ķ' => 'K',
402         'ĺ' => 'l',
403         'ļ' => 'l',
404         'ľ' => 'l',
405         'ŀ' => 'l',
406         'ł' => 'l',
407         'Ĺ' => 'L',
408         'Ļ' => 'L',
409         'Ľ' => 'L',
410         'Ŀ' => 'L',
411         'Ł' => 'L',
412         'ñ' => 'n',
413         'ń' => 'n',
414         'ņ' => 'n',
415         'ň' => 'n',
416         'ʼn' => 'n',
417         'Ñ' => 'N',
418         'Ń' => 'N',
419         'Ņ' => 'N',
420         'Ň' => 'N',
421         'ó' => 'o',
422         'ò' => 'o',
423         'ö' => 'oe',
424         'ô' => 'o',
425         'õ' => 'o',
426         'ø' => 'o',
427         'ō' => 'o',
428         'ŏ' => 'o',
429         'ő' => 'o',
430         'œ' => 'oe',
431         'ȍ' => 'o',
432         'ȏ' => 'o',
433         'Ó' => 'O',
434         'Ò' => 'O',
435         'Ö' => 'Oe',
436         'Ô' => 'O',
437         'Õ' => 'O',
438         'Ø' => 'O',
439         'Ō' => 'O',
440         'Ŏ' => 'O',
441         'Ő' => 'O',
442         'Œ' => 'OE',
443         'Ȍ' => 'O',
444         'Ȏ' => 'O',
445         'ŕ' => 'r',
446         'ř' => 'r',
447         'ȑ' => 'r',
448         'ȓ' => 'r',
449         'Ŕ' => 'R',
450         'Ř' => 'R',
451         'Ȑ' => 'R',
452         'Ȓ' => 'R',
453         'ß' => 'ss',
454         'ś' => 's',
455         'ŝ' => 's',
456         'ş' => 's',
457         'š' => 's',
458         'ș' => 's',
459         'Ś' => 'S',
460         'Ŝ' => 'S',
461         'Ş' => 'S',
462         'Š' => 'S',
463         'Ș' => 'S',
464         'ţ' => 't',
465         'ť' => 't',
466         'ŧ' => 't',
467         'ț' => 't',
468         'Ţ' => 'T',
469         'Ť' => 'T',
470         'Ŧ' => 'T',
471         'Ț' => 'T',
472         'ú' => 'u',
473         'ù' => 'u',
474         'ü' => 'ue',
475         'û' => 'u',
476         'ũ' => 'u',
477         'ū' => 'u',
478         'ŭ' => 'u',
479         'ů' => 'u',
480         'ű' => 'u',
481         'ų' => 'u',
482         'ȕ' => 'u',
483         'ȗ' => 'u',
484         'Ú' => 'U',
485         'Ù' => 'U',
486         'Ü' => 'Ue',
487         'Û' => 'U',
488         'Ũ' => 'U',
489         'Ū' => 'U',
490         'Ŭ' => 'U',
491         'Ů' => 'U',
492         'Ű' => 'U',
493         'Ų' => 'U',
494         'Ȕ' => 'U',
495         'Ȗ' => 'U',
496         'ŵ' => 'w',
497         'Ŵ' => 'W',
498         'ý' => 'y',
499         'ÿ' => 'y',
500         'ŷ' => 'y',
501         'Ý' => 'Y',
502         'Ÿ' => 'Y',
503         'Ŷ' => 'Y',
504         'ź' => 'z',
505         'ż' => 'z',
506         'ž' => 'z',
507         'Ź' => 'Z',
508         'Ż' => 'Z',
509         'Ž' => 'Z',
510     );
511
512
513     $result = strtr($string, $special_chars);   // replace known special chars
514     $result = strtoupper($result);                  // upper case
515     // make sure every special char is replaced by one space, not two or three
516     $result = mb_convert_encoding($result, 'ASCII', 'UTF-8');
517     $result = preg_replace('/[^A-Z0-9 \.,&\-\/\+\*\$%]/', ' ', $result);
518
519     return $result;
520 }
521 ?>