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
« 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
16logger = logging.getLogger(__name__)
19class Command(SafeCommand):
20 help = """
21 Download Finnish bank files
22 """
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)
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
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 # ...
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))
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))