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

76 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-27 13:36 +0700

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

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): # pylint: disable=too-many-branches 

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.order_by("id").distinct()): 

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", encoding="utf-8") 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( 

66 ws_connection, 

67 "UploadFile", 

68 file_content=file_content, 

69 file_type=file_type, 

70 verbose=options["verbose"], 

71 ) 

72 data = xml_to_dict(content, array_tags=["FileDescriptor"]) 

73 else: 

74 res = wsedi_upload_file( 

75 file_content=file_content, 

76 file_type=file_type, 

77 file_name=p.file_name, 

78 verbose=options["verbose"], 

79 ) 

80 logger.info("HTTP response {}".format(res.status_code)) 

81 logger.info(res.text) 

82 data = res.json() 

83 

84 # parse response 

85 response_code = data.get("ResponseCode", "")[:4] 

86 response_text = data.get("ResponseText", "")[:255] 

87 if response_code != "00": 

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

89 logger.error(msg) 

90 raise Exception("Response code {} ({})".format(response_code, response_text)) 

91 if "FileDescriptors" in data: 

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

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

94 file_reference = fd.get("FileReference", "") 

95 if file_reference: 

96 p.file_reference = file_reference 

97 p.save(update_fields=["file_reference"]) 

98 PayoutStatus.objects.create( 

99 payout=p, 

100 msg_id=p.msg_id, 

101 file_name=p.file_name, 

102 response_code=response_code, 

103 response_text=response_text, 

104 status_reason="File upload OK", 

105 ) 

106 

107 except Exception as e: 

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

109 logger.error(long_err) 

110 short_err = "File upload failed: " + str(e) 

111 p.state = PAYOUT_ERROR 

112 p.save(update_fields=["state"]) 

113 PayoutStatus.objects.create( 

114 payout=p, 

115 group_status=PAYOUT_ERROR, 

116 msg_id=p.msg_id, 

117 file_name=p.file_name, 

118 response_code=response_code, 

119 response_text=response_text, 

120 status_reason=short_err[:255], 

121 )