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

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

2import base64 

3import logging 

4import os 

5import pytz 

6from django.core.management.base import CommandParser 

7from django.utils.timezone import now 

8from jutil.xml import xml_to_dict 

9from jbank.helpers import parse_start_and_end_date 

10from jbank.pain002 import process_pain002_file_content 

11from jbank.models import WsEdiConnection 

12from jbank.wsedi import wsedi_get, wsedi_execute 

13from jutil.command import SafeCommand 

14 

15 

16logger = logging.getLogger(__name__) 

17 

18 

19class Command(SafeCommand): 

20 help = """ 

21 Download Finnish bank files 

22 """ 

23 

24 def add_arguments(self, parser: CommandParser): 

25 parser.add_argument("path", type=str) 

26 parser.add_argument("--verbose", action="store_true") 

27 parser.add_argument("--overwrite", action="store_true") 

28 parser.add_argument("--file-type", type=str, help="E.g. TO, SVM, XP, NDCORPAYL, pain.002.001.03") 

29 parser.add_argument("--status", type=str, default="", help="E.g. DLD, NEW") 

30 parser.add_argument("--file-reference", type=str, help="Download single file based on file reference") 

31 parser.add_argument("--list-only", action="store_true") 

32 parser.add_argument("--process-pain002", action="store_true") 

33 parser.add_argument("--start-date", type=str) 

34 parser.add_argument("--end-date", type=str) 

35 parser.add_argument("--ws", type=int) 

36 

37 def do(self, *args, **options): # pylint: disable=too-many-statements 

38 ws = WsEdiConnection.objects.get(id=options["ws"]) if options["ws"] else None 

39 assert ws is None or isinstance(ws, WsEdiConnection) 

40 if ws and not ws.enabled: 

41 logger.info("WS connection %s not enabled, exiting", ws) 

42 return 

43 

44 start_date, end_date = parse_start_and_end_date(pytz.timezone("Europe/Helsinki"), **options) 

45 path = os.path.abspath(options["path"]) 

46 command = "DownloadFileList" 

47 time_now = now() 

48 file_reference = options["file_reference"] 

49 if file_reference: 

50 command = "DownloadFile" 

51 status = options["status"] 

52 file_type = options["file_type"] 

53 if command == "DownloadFileList" and not file_type: 

54 print("--file-type required (e.g. TO, SVM, XP, NDCORPAYL, pain.002.001.03)") 

55 return 

56 if ws: 

57 content = wsedi_execute( 

58 ws, 

59 command=command, 

60 file_type=file_type, 

61 status=status, 

62 start_date=start_date, 

63 end_date=end_date, 

64 file_reference=file_reference, 

65 verbose=options["verbose"], 

66 ) 

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

68 else: 

69 res = wsedi_get( 

70 command=command, 

71 file_type=file_type, 

72 status=status, 

73 file_reference=file_reference, 

74 verbose=options["verbose"], 

75 ) 

76 data = res.json() 

77 # "FileDescriptors": { 

78 # "FileDescriptor": [ 

79 # { 

80 # "FileReference": "535283541", 

81 # "TargetId": "NONE", 

82 # "UserFilename": "STOL001.FMV80KT2.WEBSER.PS", 

83 # "ParentFileReference": "1218", 

84 # "FileType": "TO", 

85 # "FileTimestamp": "2017-12-18T20:33:09.362+02:00", 

86 # "Status": "DLD", 

87 # "LastDownloadTimestamp": "2017-12-19T12:36:34.490+02:00", 

88 # "ForwardedTimestamp": "2017-12-18T20:33:09.362+02:00", 

89 # "Deletable": "false", 

90 # "CustomerNumber": "06720106", 

91 # "Modifier": "06720106", 

92 # "ModifiedTimestamp": "2017-12-19T12:36:34.490+02:00", 

93 # "SourceId": "A", 

94 # "Environment": "PRODUCTION" 

95 # }, 

96 # ... 

97 

98 if command == "DownloadFileList": 

99 if "FileDescriptors" in data and data["FileDescriptors"] is not None and "FileDescriptor" in data["FileDescriptors"]: 

100 for fd in data["FileDescriptors"]["FileDescriptor"]: 

101 file_reference = fd["FileReference"] 

102 file_type = fd["FileType"] 

103 file_basename = file_reference + "." + file_type 

104 file_path = os.path.join(path, file_basename) 

105 if options["list_only"]: 

106 print( 

107 "{file_reference} ({file_type}/{status}): {user_filename} ({timestamp})".format( 

108 file_reference=file_reference, 

109 file_type=file_type, 

110 status=fd.get("Status"), 

111 user_filename=fd.get("UserFilename"), 

112 timestamp=fd.get("FileTimestamp"), 

113 ) 

114 ) 

115 continue 

116 if options["overwrite"] or not os.path.isfile(file_path): 

117 command = "DownloadFile" 

118 if ws: 

119 content = wsedi_execute( 

120 ws, 

121 command=command, 

122 file_type=file_type, 

123 status="", 

124 file_reference=file_reference, 

125 verbose=options["verbose"], 

126 ) 

127 file_data = xml_to_dict(content) 

128 else: 

129 res = wsedi_get( 

130 command=command, 

131 file_type=file_type, 

132 status="", 

133 file_reference=file_reference, 

134 verbose=options["verbose"], 

135 ) 

136 file_data = res.json() 

137 if "Content" not in file_data: 

138 logger.error("WS-EDI {} Content block missing: {}".format(command, file_data)) 

139 raise Exception("WS-EDI {} Content block missing".format(command)) 

140 bcontent = base64.b64decode(file_data["Content"]) 

141 with open(file_path, "wb") as fp: 

142 fp.write(bcontent) 

143 logger.info("Wrote file {}".format(file_path)) 

144 

145 # process selected files immediately 

146 if options["process_pain002"] and file_type in ["XP", "pain.002.001.03", "NDCORPAYL"]: 

147 process_pain002_file_content(bcontent, file_path, created=time_now) 

148 else: 

149 print("Skipping old file {}".format(file_path)) 

150 else: 

151 print("Empty file list downloaded") 

152 elif command == "DownloadFile": 

153 bcontent = base64.b64decode(data["Content"]) 

154 file_path = os.path.join(path, file_reference) 

155 if options["overwrite"] or not os.path.isfile(file_path): 

156 with open(file_path, "wb") as fp: 

157 fp.write(bcontent) 

158 logger.info("Wrote file {}".format(file_path)) 

159 else: 

160 print("Skipping old file {}".format(file_path))