Coverage for jbank/management/commands/parse_to.py: 77%
60 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
1import logging
2import os
3from pprint import pprint
4from django.core.management.base import CommandParser
5from django.db import transaction
6from jbank.helpers import get_or_create_bank_account, save_or_store_media
7from jbank.svm import create_statement
8from jbank.files import list_dir_files
9from jbank.models import Statement, StatementFile
10from jbank.parsers import parse_filename_suffix
11from jbank.tito import parse_tiliote_statements_from_file, TO_STATEMENT_SUFFIXES
12from jutil.command import SafeCommand
14logger = logging.getLogger(__name__)
17class Command(SafeCommand):
18 help = "Parses bank account statement .TO (tiliote) files"
20 def add_arguments(self, parser: CommandParser):
21 parser.add_argument("path", type=str)
22 parser.add_argument("--verbose", action="store_true")
23 parser.add_argument("--test", action="store_true")
24 parser.add_argument("--delete-old", action="store_true")
25 parser.add_argument("--auto-create-accounts", action="store_true")
26 parser.add_argument("--resolve-original-filenames", action="store_true")
27 parser.add_argument("--tag", type=str, default="")
29 def do(self, *args, **options): # pylint: disable=too-many-branches
30 files = list_dir_files(options["path"])
31 for filename in files:
32 plain_filename = os.path.basename(filename)
34 if parse_filename_suffix(plain_filename).upper() not in TO_STATEMENT_SUFFIXES:
35 print("Ignoring non-TO file {}".format(filename))
36 continue
38 if options["resolve_original_filenames"]:
39 found = StatementFile.objects.filter(statement__name=plain_filename).first()
40 if found and not found.original_filename:
41 assert isinstance(found, StatementFile)
42 found.original_filename = filename
43 found.save(update_fields=["original_filename"])
44 logger.info("Original TO statement filename of %s resolved to %s", found, filename)
46 if options["delete_old"]:
47 Statement.objects.filter(name=plain_filename).delete()
49 if options["test"]:
50 statements = parse_tiliote_statements_from_file(filename)
51 pprint(statements)
52 continue
54 if not Statement.objects.filter(name=plain_filename).first():
55 print("Importing statement file {}".format(filename))
57 statements = parse_tiliote_statements_from_file(filename)
58 if options["verbose"]:
59 pprint(statements)
61 with transaction.atomic():
62 file = StatementFile(original_filename=filename, tag=options["tag"])
63 file.save()
64 save_or_store_media(file.file, filename)
65 file.save()
67 for data in statements:
68 if options["auto_create_accounts"]:
69 account_number = data.get("header", {}).get("account_number")
70 if account_number:
71 get_or_create_bank_account(account_number)
73 create_statement(data, name=plain_filename, file=file) # pytype: disable=not-callable
74 else:
75 print("Skipping statement file {}".format(filename))