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-locals,too-many-branches 

2import logging 

3import traceback 

4from django.core.management.base import CommandParser 

5from jutil.xml import xml_to_dict 

6from jbank.models import Payout, PayoutStatus, PAYOUT_ERROR, PAYOUT_WAITING_UPLOAD, PAYOUT_UPLOADED, WsEdiConnection 

7from jbank.wsedi import wsedi_upload_file, wsedi_execute 

8from jutil.command import SafeCommand 

9 

10 

11logger = logging.getLogger(__name__) 

12 

13 

14class Command(SafeCommand): 

15 help = """ 

16 Upload Finnish bank files 

17 """ 

18 

19 def add_arguments(self, parser: CommandParser): 

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

21 parser.add_argument('--file-type', type=str, help='E.g. XL, NDCORPAYS, pain.001.001.03') 

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

23 parser.add_argument('--force', action='store_true') 

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

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

26 

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

28 default_ws = WsEdiConnection.objects.get(id=options['default_ws']) if options['default_ws'] else None 

29 assert default_ws is None or isinstance(default_ws, WsEdiConnection) 

30 file_type = options['file_type'] 

31 if not file_type: 

32 print('--file-type required (e.g. XL, NDCORPAYS, pain.001.001.03)') 

33 return 

34 

35 payouts = Payout.objects.all() 

36 if options['payout']: 

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

38 else: 

39 payouts = payouts.filter(state=PAYOUT_WAITING_UPLOAD) 

40 if options['ws']: 

41 payouts = payouts.filter(connection_id=options['ws']) 

42 

43 for p in list(payouts): 

44 assert isinstance(p, Payout) 

45 p.refresh_from_db() 

46 ws_connection = p.connection or default_ws 

47 

48 if p.state != PAYOUT_WAITING_UPLOAD: 

49 logger.info('Skipping {} since not in state PAYOUT_WAITING_UPLOAD'.format(p)) 

50 continue 

51 if ws_connection and not ws_connection.enabled: 

52 logger.info('WS connection %s not enabled, skipping payment %s', ws_connection, p) 

53 continue 

54 

55 response_code = '' 

56 response_text = '' 

57 try: 

58 # upload file 

59 logger.info('Uploading payment id={} {} file {}'.format(p.id, file_type, p.full_path)) 

60 with open(p.full_path, 'rt') as fp: 

61 file_content = fp.read() 

62 p.state = PAYOUT_UPLOADED 

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

64 if ws_connection: 

65 content = wsedi_execute(ws_connection, 'UploadFile', file_content=file_content, file_type=file_type, verbose=options['verbose']) 

66 data = xml_to_dict(content, array_tags=['FileDescriptor']) 

67 else: 

68 res = wsedi_upload_file(file_content=file_content, file_type=file_type, file_name=p.file_name, verbose=options['verbose']) 

69 logger.info('HTTP response {}'.format(res.status_code)) 

70 logger.info(res.text) 

71 data = res.json() 

72 

73 # parse response 

74 response_code = data.get('ResponseCode', '')[:4] 

75 response_text = data.get('ResponseText', '')[:255] 

76 if response_code != '00': 

77 msg = 'WS-EDI file {} upload failed: {} ({})'.format(p.file_name, response_text, response_code) 

78 logger.error(msg) 

79 raise Exception('Response code {} ({})'.format(response_code, response_text)) 

80 if 'FileDescriptors' in data: 

81 fds = data.get("FileDescriptors", {}).get("FileDescriptor", []) 

82 fd = {} if not fds else fds[0] 

83 file_reference = fd.get('FileReference', '') 

84 if file_reference: 

85 p.file_reference = file_reference 

86 p.save(update_fields=['file_reference']) 

87 PayoutStatus.objects.create(payout=p, msg_id=p.msg_id, file_name=p.file_name, 

88 response_code=response_code, response_text=response_text, 

89 status_reason='File upload OK') 

90 

91 except Exception as e: 

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

93 logger.error(long_err) 

94 short_err = 'File upload failed: ' + str(e) 

95 p.state = PAYOUT_ERROR 

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

97 PayoutStatus.objects.create(payout=p, group_status=PAYOUT_ERROR, msg_id=p.msg_id, file_name=p.file_name, 

98 response_code=response_code, response_text=response_text, 

99 status_reason=short_err[:255])