Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#pylint: disable=too-many-branches 

2import logging 

3import os 

4from pprint import pprint 

5from django.core.files import File 

6from django.core.management.base import CommandParser 

7from django.db import transaction 

8from jbank.camt import camt053_get_iban, camt053_create_statement, camt053_parse_statement_from_file 

9from jbank.helpers import get_or_create_bank_account 

10from jbank.files import list_dir_files 

11from jbank.models import Statement, StatementFile 

12from jutil.command import SafeCommand 

13from jutil.format import strip_media_root, is_media_full_path 

14 

15logger = logging.getLogger(__name__) 

16 

17 

18class Command(SafeCommand): 

19 help = 'Parses XML bank account statement (camt.053.001.02) files' 

20 

21 def add_arguments(self, parser: CommandParser): 

22 parser.add_argument('path', type=str) 

23 parser.add_argument('--verbose', action='store_true') 

24 parser.add_argument('--test', action='store_true') 

25 parser.add_argument('--delete-old', action='store_true') 

26 parser.add_argument('--auto-create-accounts', action='store_true') 

27 parser.add_argument('--suffix', type=str) 

28 parser.add_argument('--resolve-original-filenames', action='store_true') 

29 parser.add_argument('--tag', type=str, default='') 

30 

31 def do(self, *args, **options): 

32 files = list_dir_files(options['path'], options['suffix']) 

33 for filename in files: 

34 plain_filename = os.path.basename(filename) 

35 

36 if options['resolve_original_filenames']: 

37 found = StatementFile.objects.filter(statement__name=plain_filename).first() 

38 if found and not found.original_filename: 

39 assert isinstance(found, StatementFile) 

40 found.original_filename = filename 

41 found.save(update_fields=['original_filename']) 

42 logger.info('Original XML statement filename of %s resolved to %s', found, filename) 

43 

44 if options['delete_old']: 

45 Statement.objects.filter(name=plain_filename).delete() 

46 

47 if options['test']: 

48 statement = camt053_parse_statement_from_file(filename) 

49 pprint(statement) 

50 continue 

51 

52 if not Statement.objects.filter(name=plain_filename).first(): 

53 print('Importing statement file {}'.format(plain_filename)) 

54 

55 statement = camt053_parse_statement_from_file(filename) 

56 if options['verbose']: 

57 pprint(statement) 

58 

59 with transaction.atomic(): 

60 if not Statement.objects.filter(name=plain_filename).first(): 

61 file = StatementFile(original_filename=filename, tag=options['tag']) 

62 file.save() 

63 if is_media_full_path(filename): 

64 file.file.name = strip_media_root(filename) # type: ignore 

65 file.save() 

66 else: 

67 with open(filename, 'rb') as fp: 

68 file.file.save(plain_filename, File(fp)) 

69 for data in [statement]: 

70 if options['auto_create_accounts']: 

71 account_number = camt053_get_iban(data) 

72 if account_number: 

73 get_or_create_bank_account(account_number) 

74 

75 camt053_create_statement(data, name=plain_filename, file=file) # pytype: disable=not-callable 

76 else: 

77 print('Skipping statement file {}'.format(filename))