def __init__(self, config: Optional[str] = None): create_db() fill_db() # parse config if exists try: _config_path = Path(config) with open(_config_path) as file: _config = yaml.safe_load(file)["config"] except TypeError: LOGGER.INFO("No config file specified. Falling back to default") _config = {} except FileNotFoundError: LOGGER.INFO("Config file not found. Falling back to default") _config = {} self.name = _config.get("name", "BankLite") # defaults to BankLite self.currency = _config.get("currency", "USD") # defaults to USD self.initial_reserve = _config.get("initial_reserve", 1e9) # defaults to 1 billion self.conn = sqlite3.connect("banklite.db", check_same_thread=False) # main services self.ledger_service = LedgerService(conn=self.conn) self.account_service = AccountService(conn=self.conn) self.customer_service = CustomerService(conn=self.conn) # create reserve account self.reserve_account = self.account_service.create_reserve_account() # fill reserve with initial deposit self.ledger_service.record_entry( account=self.reserve_account, amount=self.initial_reserve )
def test_get_account_balance(database_setup): conn = database_setup account_service = AccountService(conn=conn) ledger_service = LedgerService(conn=conn) acct = BaseAccount("0000000001", "0000000001") ledger_service.record_entry(account=acct, amount=100) ledger_service.record_entry(account=acct, amount=100) assert account_service.get_account_balance(acct.account_id) == 200.0
def test_get_reserve_balance(database_setup): conn = database_setup ledger_service = LedgerService(conn=conn) acct = BaseAccount("0000000001", "0000000001") ledger_service.record_entry(account=acct, amount=10) ledger_service.record_entry(account=acct, amount=-2) balance = ledger_service.get_reserve_balance() assert balance == 8
def test_ledger_record_entry(database_setup): conn = database_setup ledger_service = LedgerService(conn=conn) acct = BaseAccount("0000000001", "0000000001") ledger_service.record_entry(account=acct, amount=200) _, account_id, load_id, amount = conn.execute( "SELECT * FROM ledger").fetchone() assert account_id == "1" assert amount == 200.0
def open_checking_account(self, customer_id: Union[str, int], deposit_amount: float) -> CheckingAccount: """ Opens a checking account for the customer associated with the ID passed in :param customer_id: ID of customer :param deposit_amount: Amount for initial account deposit :return: Checking account created """ account_service = AccountService(conn=self.conn) ledger_service = LedgerService(conn=self.conn) customer = self.get_customer_by_id(customer_id=customer_id) acct = account_service.create_checking_account(customer=customer) ledger_service.record_entry(account=acct, amount=deposit_amount) return acct
class BankLite: """ BankLite controller object """ def __init__(self, config: Optional[str] = None): create_db() fill_db() # parse config if exists try: _config_path = Path(config) with open(_config_path) as file: _config = yaml.safe_load(file)["config"] except TypeError: LOGGER.INFO("No config file specified. Falling back to default") _config = {} except FileNotFoundError: LOGGER.INFO("Config file not found. Falling back to default") _config = {} self.name = _config.get("name", "BankLite") # defaults to BankLite self.currency = _config.get("currency", "USD") # defaults to USD self.initial_reserve = _config.get("initial_reserve", 1e9) # defaults to 1 billion self.conn = sqlite3.connect("banklite.db", check_same_thread=False) # main services self.ledger_service = LedgerService(conn=self.conn) self.account_service = AccountService(conn=self.conn) self.customer_service = CustomerService(conn=self.conn) # create reserve account self.reserve_account = self.account_service.create_reserve_account() # fill reserve with initial deposit self.ledger_service.record_entry( account=self.reserve_account, amount=self.initial_reserve ) def __repr__(self): return f"BankLite(name={self.name!r})" def create_new_customer( self, customer_type: str, **kwargs ) -> Union[BaseCustomer, RetailCustomer, CommercialCustomer, None]: """ Factory object creator for customer objects :param customer_type: Either `retail` or `commercial` :return: Customer object """ if customer_type == "retail": customer = self.customer_service.create_retail_customer(**kwargs) elif customer_type == "commercial": customer = self.customer_service.create_commercial_customer(**kwargs) else: LOGGER.DEBUG("Invalid customer type: %s", customer_type) return None return customer def open_account( self, acct_type: str, customer_id: str, deposit_amount: float, savings_rate: Optional[float] = 0.0, ) -> Union[BaseAccount, None]: """ Factory object creator for account objects :param acct_type: Either `checking` or `savings` :param customer_id: ID of customer opening account :param deposit_amount: Amount to deposit (must be positive value) :param savings_rate: If the account is a savings account, a savings rate must be passed in :return: Account object """ if acct_type == "checking": account = self.customer_service.open_checking_account(customer_id, deposit_amount) elif acct_type == "savings": account = self.customer_service.open_savings_account( customer_id, deposit_amount, savings_rate ) else: LOGGER.DEBUG("Invalid account type: %s", acct_type) return None return account def deposit(self, account_id: str, amount: float) -> Union[float, None]: """ Deposit amount into an account :param account_id: ID of account :param amount: Amount to deposit :return: Resulting account balance """ account = self.account_service.get_account_by_id(account_id) if account and amount > 0: self.ledger_service.record_entry(account, amount) return self.account_service.get_account_balance(account.account_id) elif amount <= 0: return self.account_service.get_account_balance(account.account_id) else: return None def withdraw(self, account_id: str, amount: float) -> Union[float, None]: """ Withdraw amount from account :param account_id: ID of account :param amount: Amount to withdraw :return: Resulting account balance """ account = self.account_service.get_account_by_id(account_id) if amount > self.account_service.get_account_balance(account_id): return None if account and amount < 0: self.ledger_service.record_entry(account, amount) return self.account_service.get_account_balance(account.account_id) elif amount >= 0: return self.account_service.get_account_balance(account.account_id) else: return None