Coverage for jbank/management/commands/wsedi_upload.py : 0%

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
11logger = logging.getLogger(__name__)
14class Command(SafeCommand):
15 help = """
16 Upload Finnish bank files
17 """
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)
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
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'])
43 for p in list(payouts):
44 assert isinstance(p, Payout)
45 p.refresh_from_db()
46 ws_connection = p.connection or default_ws
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
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()
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')
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])