from decimal import Decimal from typing import Any from faker import Faker from polyfactory.factories.pydantic_factory import ModelFactory from polyfactory.fields import Use from src.models.b4w import B4wExport from src.models.comdirect import ComdirectCreditCard, ComdirectDepot, ComdirectGiro from src.models.transactions import Transaction DEFAULT_CATEGORY = "root_category:parent_category:leaf_category" def _faker_or_none(faker: Faker, non_default: Any, default: Any = None, p_value=0.5): if faker.pyfloat(min_value=0.0, max_value=1.0) < p_value: return default return non_default def _amount() -> Decimal: return B4wExportFactory.__faker__.pydecimal( left_digits=6, right_digits=2, positive=True, min_value=Decimal("0.01"), ) def _amount_eur() -> str: """Generate German-formatted decimal string (e.g., '32,43').""" val = Faker().pydecimal( right_digits=2, min_value=Decimal("-4000.00"), max_value=Decimal("4000.00") ) # Format as German string with comma decimal separator return f"{val:.2f}".replace(".", ",").strip() def _german_date() -> str: return Faker().date("%d.%m.%Y") def _sentence() -> str: return B4wExportFactory.__faker__.sentence( nb_words=8, variable_nb_words=False, ) def _names() -> str: return B4wExportFactory.__faker__.company() def _iban() -> str: return B4wExportFactory.__faker__.iban() def _iban_or_none() -> str: return _faker_or_none(Faker(), Faker().iban(), default="") class B4wExportFactory(ModelFactory[B4wExport]): __faker__ = Faker("de_DE") __use_examples__ = True Amt = Use(_amount) RmtInf = Use(_sentence) Notes = Use(_sentence) RmtdNm = Use(_names) OwnrAcctIBAN = Use(_iban) RmtdAcctIBAN = Use(_iban_or_none) class ComdirectGiroFactory(ModelFactory[ComdirectGiro]): __faker__ = Faker("de_DE") __use_examples__ = True text = Use(_sentence) amount_eur = Use(_amount_eur) date_val = Use(_german_date) date_book = Use(_german_date) class ComdirectCreditCardFactory(ModelFactory[ComdirectCreditCard]): __faker__ = Faker("de_DE") __use_examples__ = True text = Use(_sentence) amount_eur = Use(_amount_eur) date_val = Use(_german_date) date_book = Use(_german_date) class ComdirectDepotFactory(ModelFactory[ComdirectDepot]): __faker__ = Faker("de_DE") __use_examples__ = True amount_eur = Use(_amount_eur) date_val = Use(_german_date) num = Use(_amount_eur) spot_price = Use(_amount_eur) class TransactionFactory(ModelFactory[Transaction]): __faker__ = Faker("de_DE") __use_examples__ = True account_iban = Use(_iban) text = Use(_sentence) other_name = Use(_names) other_iban = Use(_iban_or_none)