Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#pylint: disable=logging-format-interpolation,too-many-branches 

2import logging 

3import os 

4import traceback 

5from django.core.management.base import CommandParser 

6from jbank.models import Payout, PAYOUT_ERROR, PAYOUT_WAITING_PROCESSING, PayoutStatus, PAYOUT_WAITING_UPLOAD, \ 

7 WsEdiConnection 

8from jbank.sepa import Pain001, PAIN001_REMITTANCE_INFO_MSG, PAIN001_REMITTANCE_INFO_OCR_ISO, \ 

9 PAIN001_REMITTANCE_INFO_OCR 

10from jutil.command import SafeCommand 

11 

12 

13logger = logging.getLogger(__name__) 

14 

15 

16class Command(SafeCommand): 

17 help = """ 

18 Generates pain.001.001.03 compatible SEPA payment files from pending Payout objects. 

19 By default generates files of Payouts in WAITING_PROCESSING state. 

20 """ 

21 

22 def add_arguments(self, parser: CommandParser): 

23 parser.add_argument('dir', type=str) 

24 parser.add_argument('--payout', type=int) 

25 parser.add_argument('--verbose', action='store_true') 

26 parser.add_argument('--ws', type=int) 

27 parser.add_argument('--suffix', type=str, default='XL') 

28 

29 def do(self, *args, **options): 

30 target_dir = options['dir'] 

31 if options['verbose']: 

32 logger.info('Writing pain.001 files to {}'.format(target_dir)) 

33 

34 payouts = Payout.objects.all() 

35 if options['payout']: 

36 payouts = Payout.objects.filter(id=options['payout']) 

37 else: 

38 payouts = payouts.filter(state=PAYOUT_WAITING_PROCESSING) 

39 if options['ws']: 

40 ws = WsEdiConnection.objects.get(id=options['ws']) 

41 assert isinstance(ws, WsEdiConnection) 

42 if ws and not ws.enabled: 

43 logger.info('WS connection %s not enabled, exiting', ws) 

44 return 

45 payouts = payouts.filter(connection=ws) 

46 

47 for p in list(payouts): 

48 assert isinstance(p, Payout) 

49 try: 

50 if options['verbose']: 

51 print(p) 

52 

53 if not p.msg_id: 

54 p.generate_msg_id() 

55 if not p.file_name: 

56 p.file_name = p.msg_id + '.' + options['suffix'] 

57 p.save(update_fields=['file_name']) 

58 

59 pain001 = Pain001(p.msg_id, p.payer.name, p.payer.account_number, p.payer.bic, p.payer.org_id, p.payer.address_lines, p.payer.country_code) 

60 if p.messages: 

61 remittance_info = p.messages 

62 remittance_info_type = PAIN001_REMITTANCE_INFO_MSG 

63 else: 

64 remittance_info = p.reference 

65 remittance_info_type = PAIN001_REMITTANCE_INFO_OCR_ISO if remittance_info[:2] == 'RF' else PAIN001_REMITTANCE_INFO_OCR 

66 pain001.add_payment(p.msg_id, p.recipient.name, p.recipient.account_number, p.recipient.bic, 

67 p.amount, remittance_info, remittance_info_type, p.due_date) 

68 

69 p.full_path = full_path = os.path.join(target_dir, p.file_name) 

70 if options['verbose']: 

71 print(p, 'written to', full_path) 

72 pain001.render_to_file(full_path) 

73 logger.info('{} generated'.format(full_path)) 

74 p.state = PAYOUT_WAITING_UPLOAD 

75 p.save(update_fields=['full_path', 'state']) 

76 

77 PayoutStatus.objects.create(payout=p, file_name=p.file_name, msg_id=p.msg_id, status_reason="File generation OK") 

78 except Exception as e: 

79 short_err = 'File generation failed: ' + str(e) 

80 long_err = "File generation failed ({}): ".format(p.file_name) + traceback.format_exc() 

81 logger.error(long_err) 

82 p.state = PAYOUT_ERROR 

83 p.save(update_fields=['state']) 

84 PayoutStatus.objects.create(payout=p, group_status=PAYOUT_ERROR, file_name=p.file_name, msg_id=p.msg_id, status_reason=short_err[:255])