示例#1
0
    def do(self, *args, **options):  # pylint: disable=too-many-branches
        files = list_dir_files(options["path"])
        # pprint(files)
        for filename in files:
            plain_filename = os.path.basename(filename)

            if parse_filename_suffix(
                    plain_filename).upper() not in SVM_STATEMENT_SUFFIXES:
                print("Ignoring non-SVM file {}".format(filename))
                continue

            if options["resolve_original_filenames"]:
                found = ReferencePaymentBatchFile.objects.filter(
                    referencepaymentbatch__name=plain_filename).first()
                if found and not found.original_filename:
                    assert isinstance(found, ReferencePaymentBatchFile)
                    found.original_filename = filename
                    found.save(update_fields=["original_filename"])
                    logger.info(
                        "Original SVM reference payment batch filename of %s resolved to %s",
                        found, filename)

            if options["delete_old"]:
                ReferencePaymentBatch.objects.filter(
                    name=plain_filename).delete()

            if options["test"]:
                batches = parse_svm_batches_from_file(filename)
                pprint(batches)
                continue

            if not ReferencePaymentBatch.objects.filter(
                    name=plain_filename).first():
                print("Importing statement file {}".format(filename))

                batches = parse_svm_batches_from_file(filename)
                if options["verbose"]:
                    pprint(batches)

                with transaction.atomic():
                    file = ReferencePaymentBatchFile(
                        original_filename=filename, tag=options["tag"])
                    file.save()
                    save_or_store_media(file.file, filename)
                    file.save()

                    for data in batches:
                        if options["auto_create_accounts"]:
                            for rec_data in data["records"]:
                                account_number = rec_data.get("account_number")
                                if account_number:
                                    get_or_create_bank_account(account_number)

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

                    file.get_total_amount(force=True)
            else:
                print("Skipping reference payment file {}".format(filename))
示例#2
0
def parse_tiliote_statements_from_file(filename: str) -> list:
    if parse_filename_suffix(filename).upper() not in TO_STATEMENT_SUFFIXES:
        raise ValidationError(
            _('File {filename} has unrecognized ({suffixes}) suffix for file type "{file_type}"'
              ).format(filename=filename,
                       suffixes=", ".join(TO_STATEMENT_SUFFIXES),
                       file_type="tiliote"))
    with open(filename, "rt", encoding="ISO-8859-1") as fp:
        return parse_tiliote_statements(
            fp.read(), filename=basename(filename))  # type: ignore
示例#3
0
def parse_aeb43_statements_from_file(filename: str) -> list:
    if parse_filename_suffix(filename).upper() not in AEB43_STATEMENT_SUFFIXES:
        raise ValidationError(
            _('File {filename} has unrecognized ({suffixes}) suffix for file type "{file_type}"'
              ).format(filename=filename,
                       suffixes=", ".join(AEB43_STATEMENT_SUFFIXES),
                       file_type="AEB43"))
    with open(filename, "rt", encoding="UTF-8") as fp:
        return parse_aeb43_statements(
            fp.read(), filename=os.path.basename(filename))  # type: ignore
示例#4
0
    def do(self, *args, **kwargs):
        files = list_dir_files(kwargs["path"])
        for filename in files:
            plain_filename = os.path.basename(filename)

            if parse_filename_suffix(plain_filename).upper() not in AEB43_STATEMENT_SUFFIXES:
                print("Ignoring non-AEB43 file {}".format(filename))
                continue

            batches = parse_aeb43_statements_from_file(filename)
            pprint(batches)
示例#5
0
def camt053_parse_statement_from_file(filename: str) -> dict:
    if parse_filename_suffix(
            filename).upper() not in CAMT053_STATEMENT_SUFFIXES:
        raise ValidationError(
            _('File {filename} has unrecognized ({suffixes}) suffix for file type "{file_type}"'
              ).format(filename=filename,
                       suffixes=", ".join(CAMT053_STATEMENT_SUFFIXES),
                       file_type="camt.053"))
    with open(filename, "rb") as fp:
        data = xml_to_dict(fp.read(),
                           array_tags=CAMT053_ARRAY_TAGS,
                           int_tags=CAMT053_INT_TAGS)
        return data
示例#6
0
    def do(self, *args, **options):  # pylint: disable=too-many-branches
        if options["parse_creditor_account_data"]:
            self.parse_creditor_account_data()
            return

        files = list_dir_files(options["path"], options["suffix"])
        for filename in files:
            plain_filename = os.path.basename(filename)

            if parse_filename_suffix(plain_filename).upper() not in CAMT053_STATEMENT_SUFFIXES:
                print("Ignoring non-CAMT53 file {}".format(filename))
                continue

            if options["resolve_original_filenames"]:
                found = StatementFile.objects.filter(statement__name=plain_filename).first()
                if found and not found.original_filename:
                    assert isinstance(found, StatementFile)
                    found.original_filename = filename
                    found.save(update_fields=["original_filename"])
                    logger.info("Original XML statement filename of %s resolved to %s", found, filename)

            if options["test"]:
                statement = camt053_parse_statement_from_file(filename)
                pprint(statement)
                continue

            if options["delete_old"]:
                Statement.objects.filter(name=plain_filename).delete()

            if not Statement.objects.filter(name=plain_filename).first():
                print("Importing statement file {}".format(plain_filename))

                statement = camt053_parse_statement_from_file(filename)
                if options["verbose"]:
                    pprint(statement)

                with transaction.atomic():
                    file = StatementFile(original_filename=filename, tag=options["tag"])
                    file.save()
                    save_or_store_media(file.file, filename)
                    file.save()

                    for data in [statement]:
                        if options["auto_create_accounts"]:
                            account_number = camt053_get_iban(data)
                            if account_number:
                                get_or_create_bank_account(account_number)

                        camt053_create_statement(data, name=plain_filename, file=file)  # pytype: disable=not-callable
            else:
                print("Skipping statement file {}".format(filename))
示例#7
0
    def parse_creditor_account_data(self):  # pylint: disable=too-many-locals,too-many-branches
        for sf in StatementFile.objects.all():  # pylint: disable=too-many-nested-blocks
            assert isinstance(sf, StatementFile)
            full_path = sf.full_path
            if os.path.isfile(full_path) and parse_filename_suffix(full_path).upper() in CAMT053_STATEMENT_SUFFIXES:
                logger.info("Parsing creditor account data of %s", full_path)
                statement_data = camt053_parse_statement_from_file(full_path)
                d_stmt = statement_data.get("BkToCstmrStmt", {}).get("Stmt", {})
                d_ntry = d_stmt.get("Ntry", [])
                recs = list(StatementRecord.objects.all().filter(statement__file=sf).order_by("id"))
                if len(recs) != len(d_ntry):
                    raise ValidationError(f"Statement record counts do not match in id={sf.id} ({sf})")
                for ix, ntry in enumerate(d_ntry):
                    rec = recs[ix]
                    assert isinstance(rec, StatementRecord)
                    for dtl_batch in ntry.get("NtryDtls", []):
                        rec_detail_list = list(StatementRecordDetail.objects.all().filter(record=rec))
                        if len(rec_detail_list) != len(dtl_batch.get("TxDtls", [])):
                            raise ValidationError(f"Statement record detail counts do not match in id={sf.id} ({sf})")
                        for dtl_ix, dtl in enumerate(dtl_batch.get("TxDtls", [])):
                            d = rec_detail_list[dtl_ix]
                            assert isinstance(d, StatementRecordDetail)
                            d_parties = dtl.get("RltdPties", {})
                            d_dbt = d_parties.get("Dbtr", {})
                            d.debtor_name = d_dbt.get("Nm", "")
                            d_udbt = d_parties.get("UltmtDbtr", {})
                            d.ultimate_debtor_name = d_udbt.get("Nm", "")
                            d_cdtr = d_parties.get("Cdtr", {})
                            d.creditor_name = d_cdtr.get("Nm", "")
                            d_cdtr_acct = d_parties.get("CdtrAcct", {})
                            d_cdtr_acct_id = d_cdtr_acct.get("Id", {})
                            d.creditor_account = d_cdtr_acct_id.get("IBAN", "")
                            if d.creditor_account:
                                d.creditor_account_scheme = "IBAN"
                            else:
                                d_cdtr_acct_id_othr = d_cdtr_acct_id.get("Othr") or {}
                                d.creditor_account_scheme = d_cdtr_acct_id_othr.get("SchmeNm", {}).get("Cd", "")
                                d.creditor_account = d_cdtr_acct_id_othr.get("Id") or ""
                            logger.info("%s creditor_account %s (%s)", rec, d.creditor_account, d.creditor_account_scheme)
                            d.save()

                    if not rec.recipient_account_number:
                        rec.recipient_account_number = camt053_get_unified_str(rec.detail_set.all(), "creditor_account")
                        if rec.recipient_account_number:
                            rec.save(update_fields=["recipient_account_number"])
                            logger.info("%s recipient_account_number %s", rec, rec.recipient_account_number)