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

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

2 import base64

3 import logging

4 import os

5 import pytz

6 from django.core.management.base import CommandParser

7 from django.utils.timezone import now

8 from jutil.xml import xml_to_dict

9 from jbank.helpers import parse_start_and_end_date

10 from jbank.pain002 import process_pain002_file_content

11 from jbank.models import WsEdiConnection

12 from jbank.wsedi import wsedi_get, wsedi_execute

13 from jutil.command import SafeCommand

14

15

16 logger = logging.getLogger(__name__)

17

18

19 class 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))