def __init__(self, secrets): self.brim_username = secrets.getSecret('brim.username').strip() self.brim_password = secrets.getSecret('brim.password').strip() self.brim_card_id = secrets.getSecret('brim.card_id').strip() self.brim_ynab_account_id = secrets.getSecret( 'brim.ynab_account_id').strip() self.brim_ynab_budget_id = secrets.getSecret( 'brim.ynab_budget_id').strip() self.ynab_token = secrets.getSecret( "ynab_token").strip() self.ynabClient = YNAB(self.ynab_token) self.logger = logging.getLogger('brim')
def send_transactions(config, bank_config, transactions): ynab = YNAB(config.access_token) #YNAB doesn't accept future-dated transactions, but ING sometimes produces them #just drop them from import until their actual booking date transactions = filter(lambda t: date.fromisoformat(t.date) <= date.today(), transactions) transfer_payee_id = "" if config.cash_account_id != "": cash_account = ynab.accounts.get_account(config.budget_id, config.cash_account_id) transfer_payee_id = cash_account.data.account.transfer_payee_id def create_request(transaction): return TransactionRequest( account_id=bank_config.ynab_account_id, date=transaction.date, amount=transaction.amount, memo=transaction.memo[:199] if transaction.memo else None, cleared='cleared', payee_name=None if transaction.cash_withdrawl and transfer_payee_id != "" else transaction.payee, payee_id=transfer_payee_id if transaction.cash_withdrawl and transfer_payee_id != "" else None, # import_id can only be 36 characters import_id=("API:" + transaction.hash)[:36]) transaction_req = list(map(create_request, transactions)) response = ynab.transactions.create_transactions(config.budget_id, transaction_req) if response: if 'error' in response: print( f'Account {bank_config.iban}: YNAB import failed with Error: {response}' ) elif 'data' in response: if response['data']['duplicate_import_ids']: print( f'Account {bank_config.iban}: {len(response["data"]["duplicate_import_ids"])} duplicate transations were not imported' ) if response['data']['transaction_ids']: print( f'Account {bank_config.iban}: {len(response["data"]["transaction_ids"])} transactions imported to YNAB' ) else: print('Connection to YNAB API failed')
def send_transactions(config, bank_config, transactions): ynab = YNAB(config.access_token) transfer_payee_id = "" if config.cash_account_id != "": cash_account = ynab.accounts.get_account(config.budget_id, config.cash_account_id) transfer_payee_id = cash_account.data.account.transfer_payee_id def create_request(transaction): return TransactionRequest( account_id=bank_config.ynab_account_id, date=transaction.date, amount=transaction.amount, memo=transaction.memo[:199] if transaction.memo else None, cleared='cleared', payee_name=None if transaction.cash_withdrawl and transfer_payee_id != "" else transaction.payee, payee_id=transfer_payee_id if transaction.cash_withdrawl and transfer_payee_id != "" else None, import_id=f'API:{transaction.amount}:{transaction.date}') transaction_req = list(map(create_request, transactions)) response = ynab.transactions.create_transactions(config.budget_id, transaction_req) if response: if 'error' in response: print( f'Account {bold(bank_config.iban)}: YNAB import failed with Error: {response}' ) elif 'data' in response: if response['data']['duplicate_import_ids']: print( f'Account {bank_config.iban}: {len(response["data"]["duplicate_import_ids"])} duplicate transations were not imported' ) if response['data']['transaction_ids']: print( f'Account {bank_config.iban}: {len(response["data"]["transaction_ids"])} transactions imported to YNAB' ) else: print('Connection to YNAB API failed')
def __init__(self, Secrets): self.plaid_client_id = Secrets.getSecret("plaid.client_id") self.plaid_secret = Secrets.getSecret("plaid.secret") self.plaid_env = Secrets.getSecret("plaid.env") self.plaid_tokens = Secrets.getSecret("plaid.access_tokens") self.account_mapping = Secrets.getSecret("plaid.account_mappings") self.ynab_token = Secrets.getSecret("ynab_token").strip() self.ynab_budget_id = Secrets.getSecret("plaid.ynab_budget_id").strip() self.logger = logging.getLogger("plaid") self.plaidClient = plaid.Client( client_id=self.plaid_client_id, secret=self.plaid_secret, environment=self.plaid_env, ) self.ynabClient = YNAB(self.ynab_token)
def __init__(self, Secrets): self.ynab_budget_id = Secrets.getSecret( 'splitwise.ynab_budget_id').strip() self.ynab_splitwise_account_id = Secrets.getSecret( 'splitwise.ynab_splitwise_account_id').strip() self.splitwise_group_names = Secrets.getSecret( 'splitwise.splitwise_group_names') self.dated_after = Secrets.getSecret( 'splitwise.import_dated_after') or None consumer_key = Secrets.getSecret('splitwise.consumer_key').strip() consumer_secret = Secrets.getSecret( 'splitwise.consumer_secret').strip() oauth_token = Secrets.getSecret('splitwise.oauth_token').strip() oauth_token_secret = Secrets.getSecret( 'splitwise.oauth_token_secret').strip() self.logger = logging.getLogger('splitwise') self.splitwise = Splitwise(consumer_key, consumer_secret) access_token = { 'oauth_token': oauth_token, 'oauth_token_secret': oauth_token_secret } self.splitwise.setAccessToken(access_token) self.currentUserId = self.splitwise.getCurrentUser().getId() self.spltiwise_group_double_map = {} groups = self.splitwise.getGroups() for g in groups: self.spltiwise_group_double_map[g.getId()] = g.getName() self.spltiwise_group_double_map[g.getName()] = g.getId() self.ynab_token = Secrets.getSecret("ynab_token").strip() self.ynabClient = YNAB(self.ynab_token)
async def update_data(self): """Update data.""" try: # setup YNAB API self.ynab = YNAB(self.api_key) self.get_data = self.ynab.budgets.get_budget( self.budget).data.budget # get to be budgeted data self.hass.data[DOMAIN_DATA]["to_be_budgeted"] = ( self.get_data.months[0].to_be_budgeted / 1000) _LOGGER.debug( "Recieved data for: to be budgeted: %s", (self.get_data.months[0].to_be_budgeted / 1000), ) # get unapproved transactions unapproved_transactions = len([ t.amount for t in self.get_data.transactions if t.approved is not True ]) self.hass.data[DOMAIN_DATA][ "need_approval"] = unapproved_transactions _LOGGER.debug( "Recieved data for: unapproved transactions: %s", unapproved_transactions, ) # get number of uncleared transactions uncleared_transactions = len([ t.amount for t in self.get_data.transactions if t.cleared == "uncleared" ]) self.hass.data[DOMAIN_DATA][ "uncleared_transactions"] = uncleared_transactions _LOGGER.debug("Recieved data for: uncleared transactions: %s", uncleared_transactions) total_balance = 0 # get account data for a in self.get_data.accounts: if a.on_budget: total_balance += a.balance # get to be budgeted data self.hass.data[DOMAIN_DATA]["total_balance"] = total_balance / 1000 _LOGGER.debug( "Recieved data for: total balance: %s", (self.hass.data[DOMAIN_DATA]["total_balance"]), ) # get current month data for m in self.get_data.months: if m.month != date.today().strftime("%Y-%m-01"): continue else: # budgeted self.hass.data[DOMAIN_DATA]["budgeted_this_month"] = ( m.budgeted / 1000) _LOGGER.debug( "Recieved data for: budgeted this month: %s", self.hass.data[DOMAIN_DATA]["budgeted_this_month"], ) # activity self.hass.data[DOMAIN_DATA]["activity_this_month"] = ( m.activity / 1000) _LOGGER.debug( "Recieved data for: activity this month: %s", self.hass.data[DOMAIN_DATA]["activity_this_month"], ) # get number of overspend categories overspent_categories = len( [c.balance for c in m.categories if c.balance < 0]) self.hass.data[DOMAIN_DATA][ "overspent_categories"] = overspent_categories _LOGGER.debug( "Recieved data for: overspent categories: %s", overspent_categories, ) # get remaining category balances for c in m.categories: if c.name not in self.categories: continue else: self.hass.data[DOMAIN_DATA].update([ (c.name, c.balance / 1000) ]) _LOGGER.debug( "Recieved data for categories: %s", [c.name, c.balance / 1000], ) # print(self.hass.data[DOMAIN_DATA]) except Exception as error: _LOGGER.error("Could not retrieve data - verify API key %s", error)
async def update_data(self): """Update data.""" # setup YNAB API self.ynab = YNAB(self.api_key) self.all_budgets = await self.hass.async_add_executor_job( self.ynab.budgets.get_budgets) self.raw_budget = await self.hass.async_add_executor_job( self.ynab.budgets.get_budget, self.budget) # get budget summary self.get_all_budgets = self.all_budgets.data.budgets if self.get_all_budgets: _LOGGER.debug("Found %s budgets", len(self.get_all_budgets)) for budget in self.get_all_budgets: _LOGGER.debug("Budget name: %s - id: %s", budget.name, budget.id) else: _LOGGER.errors("Unable to retrieve budgets summary") self.get_data = self.raw_budget.data.budget _LOGGER.debug("Retrieving data from budget id: %s", self.get_data.id) # get to be budgeted data self.hass.data[DOMAIN_DATA]["to_be_budgeted"] = ( self.get_data.months[0].to_be_budgeted / 1000) _LOGGER.debug( "Received data for: to be budgeted: %s", (self.get_data.months[0].to_be_budgeted / 1000), ) # get unapproved transactions unapproved_transactions = len([ t.amount for t in self.get_data.transactions if t.approved is not True ]) self.hass.data[DOMAIN_DATA]["need_approval"] = unapproved_transactions _LOGGER.debug( "Received data for: unapproved transactions: %s", unapproved_transactions, ) # get number of uncleared transactions uncleared_transactions = len([ t.amount for t in self.get_data.transactions if t.cleared == "uncleared" ]) self.hass.data[DOMAIN_DATA][ "uncleared_transactions"] = uncleared_transactions _LOGGER.debug("Received data for: uncleared transactions: %s", uncleared_transactions) total_balance = 0 # get account data for a in self.get_data.accounts: if a.on_budget: total_balance += a.balance # get to be budgeted data self.hass.data[DOMAIN_DATA]["total_balance"] = total_balance / 1000 _LOGGER.debug( "Received data for: total balance: %s", (self.hass.data[DOMAIN_DATA]["total_balance"]), ) # get current month data for m in self.get_data.months: if m.month != date.today().strftime("%Y-%m-01"): continue else: # budgeted self.hass.data[DOMAIN_DATA][ "budgeted_this_month"] = m.budgeted / 1000 _LOGGER.debug( "Received data for: budgeted this month: %s", self.hass.data[DOMAIN_DATA]["budgeted_this_month"], ) # activity self.hass.data[DOMAIN_DATA][ "activity_this_month"] = m.activity / 1000 _LOGGER.debug( "Received data for: activity this month: %s", self.hass.data[DOMAIN_DATA]["activity_this_month"], ) # get number of overspend categories overspent_categories = len( [c.balance for c in m.categories if c.balance < 0]) self.hass.data[DOMAIN_DATA][ "overspent_categories"] = overspent_categories _LOGGER.debug( "Received data for: overspent categories: %s", overspent_categories, ) # get remaining category balances for c in m.categories: if c.name not in self.categories: continue else: self.hass.data[DOMAIN_DATA].update([ (c.name, c.balance / 1000) ]) _LOGGER.debug( "Received data for categories: %s", [c.name, c.balance / 1000], )
def setUp(self): self.client = DummyClient() self.ynab = YNAB(client=self.client)
""" Use to figure out if the issue with YNAB component is related to the component itself or the package it uses to interact with YNAB To run, you must have python3 and ynab-sdk installed on the machine Install using pip3 install ynab-sdk Replace API_KEY_HERE with your API key Run the file using python3 apitest.py If everything works, you should see a summary of your budgets Otherwise you will see an error """ from ynab_sdk import YNAB try: api_key = "API_KEY_HERE" apicheck = YNAB(api_key) # print(apicheck.budgets.get_budgets()) # data = apicheck.budgets.get_budget("BUDGET_ID") # print(data.data.budget.id) except Exception: raise