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