Example #1
0
    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_by_id_not_exists(database_setup):
    conn = database_setup
    account_service = AccountService(conn=conn)

    acct = account_service.get_account_by_id("1234567890")

    assert acct is None
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_savings_account_creation(database_setup):
    conn = database_setup
    account_service = AccountService(conn=conn)

    customer = BaseCustomer("1111111111", 11111, "555-555-5555", "*****@*****.**")
    account_service.create_savings_account(customer=customer, rate=0.03)

    acct_id, customer_id, _, acct_type, acct_rate = conn.execute(
        "SELECT * FROM accounts"
    ).fetchall()[0]

    assert acct_type == 2
    assert acct_rate == 0.03
def test_get_reserve_account_by_id(database_setup):
    conn = database_setup
    account_service = AccountService(conn=conn)

    account_service.create_reserve_account()

    acct = account_service.get_account_by_id("1")

    assert acct is not None
    assert type(acct) == ReserveAccount
    assert acct.account_id == "0000000001"
    assert acct.customer_id is None
    assert acct.type == 0
    assert acct.rate == 0.0
def test_reserve_account_creation(database_setup):
    conn = database_setup
    account_service = AccountService(conn=conn)

    account_service.create_reserve_account()

    acct_id, customer_id, _, acct_type, acct_rate = conn.execute(
        "SELECT * FROM accounts"
    ).fetchall()[0]

    assert acct_id == "1"
    assert customer_id is None
    assert acct_type == 0
    assert acct_rate == 0.0
Example #7
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
def test_get_checking_account_by_id(database_setup):
    conn = database_setup
    account_service = AccountService(conn=conn)

    conn.execute(
        """
        INSERT INTO accounts
        values ('1234567890', '1234567890', DATETIME('now'), 1, 0.0)
        """
    )

    acct = account_service.get_account_by_id("1234567890")

    assert acct is not None
    assert type(acct) == CheckingAccount
    assert acct.account_id == "1234567890"
    assert acct.customer_id == "1234567890"
    assert acct.type == 1
    assert acct.rate == 0.0
def test_get_accounts_by_id(database_setup):
    conn = database_setup
    account_service = AccountService(conn=conn)

    conn.execute(
        """
        INSERT INTO accounts
        VALUES ('1111111111', '1234567890', DATETIME('now'), 1, 0.0),
               ('2222222222', '1234567891', DATETIME('now'), 1, 0.0),
               ('3333333333', '1234567892', DATETIME('now'), 2, 0.03)
        """
    )

    accts = account_service.get_accounts_by_id(["1111111111", "2222222222", "3333333333"])

    assert len(accts) == 3

    acct1 = accts[0]

    assert type(acct1) == CheckingAccount
    assert acct1.account_id == "1111111111"
    assert acct1.customer_id == "1234567890"
    assert acct1.type == 1
    assert acct1.rate == 0.0

    acct2 = accts[1]

    assert type(acct2) == CheckingAccount
    assert acct2.account_id == "2222222222"
    assert acct2.customer_id == "1234567891"
    assert acct2.type == 1
    assert acct2.rate == 0.0

    acct3 = accts[2]

    assert type(acct3) == SavingsAccount
    assert acct3.account_id == "3333333333"
    assert acct3.customer_id == "1234567892"
    assert acct3.type == 2
    assert acct3.rate == 0.03
def test_list_accounts(database_setup):
    conn = database_setup
    customer_service = CustomerService(conn)
    account_service = AccountService(conn)

    customer = customer_service.create_retail_customer(11111, "555-555-5555",
                                                       "*****@*****.**",
                                                       "111-11-1111", "John",
                                                       "Doe")

    customer_id = customer.customer_id

    account_service.create_checking_account(customer)
    account_service.create_checking_account(customer)
    account_service.create_checking_account(customer)

    accounts = customer_service.list_accounts(customer_id)

    assert len(accounts) == 3
Example #11
0
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