def parse(self, string): """ Returns ------- powl.actiondata.TransactionData Contains data to perform a transaction action. Raises ------ ValueError If amount is not a float. If a value for TransactionData is missing. """ data = actiondata.TransactionData() params = string.split(self._DELIMITER, self._MAX_SPLITS) if len(params) < self._NUM_PARAMS: msg = "not enough arguments from ({0})".format(string) err = exception.create(ValueError, msg) raise err data.debit = params[self._POSITION_DEBIT] data.credit = params[self._POSITION_CREDIT] data.amount = params[self._POSITION_AMOUNT] data.memo = params[self._POSITION_MEMO] try: float(data.amount) except ValueError: msg = "amount ({0}) is not a number".format(data.amount) err = exception.create(ValueError, msg) raise err return data
def parse(self, string): """ Returns ------- powl.actiondata.TransactionData Contains data to perform a transaction action. Raises ------ ValueError If amount is not a float. If a value for TransactionData is missing. """ data = actiondata.TransactionData() params = string.split(self._TOKEN_FLAG) for param in params: if re.match(self._TOKEN_DEBIT, param): data.debit = re.sub(self._TOKEN_DEBIT, "", param) data.debit = data.debit.strip() elif re.match(self._TOKEN_CREDIT, param): data.credit = re.sub(self._TOKEN_CREDIT, "", param) data.credit = data.credit.strip() elif re.match(self._TOKEN_AMOUNT, param): data.amount = re.sub(self._TOKEN_AMOUNT, "", param) data.amount = data.amount.strip() elif re.match(self._TOKEN_MEMO, param): data.memo = re.sub(self._TOKEN_MEMO, "", param) data.memo = data.memo.replace('"', "") data.memo = data.memo.strip() if not data.debit: msg = "debit is missing from ({0})".format(string) err = exception.create(ValueError, msg) raise err if not data.credit: msg = "credit is missing from ({0})".format(string) err = exception.create(ValueError, msg) raise err if not data.amount: msg = "amount is missing from ({0})".format(string) err = exception.create(ValueError, msg) raise err if not data.memo: msg = "memo is missing from ({0})".format(string) err = exception.create(ValueError, msg) raise err try: float(data.amount) except ValueError as err: message = "amount ({0}) is not a number".format(data.amount) exception.add_message(err, message) raise return data
def parse(self, string): """ Returns ------- powl.actiondata.BodyCompositionData Contains data to perform a body composition action. Raises ------ ValueError If mass or fat percentage is not a float. If a value for BodyCompositionData is missing. """ data = actiondata.BodyCompositionData() params = string.split(self._TOKEN_FLAG) for param in params: if re.match(self._TOKEN_MASS, param): data.mass = re.sub(self._TOKEN_MASS, "", param) data.mass = data.mass.strip() elif re.match(self._TOKEN_FAT, param): data.fat_percentage = re.sub(self._TOKEN_FAT, "", param) data.fat_percentage = data.fat_percentage.strip() if not data.mass: msg = "mass was not parsed from ({0})".format(string) err = exception.create(ValueError, msg) raise err if not data.fat_percentage: msg = "fat percentage was not parsed " + "from ({0})".format(string) err = exception.create(ValueError, msg) raise err try: float(data.mass) except ValueError as err: msg = "mass ({0}) is not a number".format(data.mass) exception.add_message(err, msg) raise try: float(data.fat_percentage) except ValueError as err: msg = "fat percentage ({0}) ".format(data.fat_percentage) + "is not a number" exception.add_message(err, msg) raise return data
def test__create__return_is_input_type(self): """ Test that the returned exception is the correct type. """ exception_type = ValueError err = exception.create(exception_type, "") self.assertEqual(exception_type, type(err))
def _assert_logged_in(self): """ Raise exception if not logged in to IMAP server. """ if not self._logged_in: errmsg = _ERRMSG_NOT_LOGGED_IN err = exception.create(ValueError, errmsg) raise err
def _assert_connected(self): """ Raise exception if not connected to IMAP server. """ if not self._imap: errmsg = _ERRMSG_NOT_CONNECTED err = exception.create(ValueError, errmsg) raise err
def _get_transfer_account(self, debit, credit): """ Get the associated QIF account from the debit and credit keys. Parameters ---------- debit : str Account key for the debit of a transaction. credit : str Account key for the credit of a transaction. Raises ------ KeyError If neither key has an associated QIF file. If neither key has an associated QIF account. Notes ----- Credit key has priority so if both debit and credit key has an associated QIF account than the QIF account associated with the credit key is returned. This is linked with get_qif_file. If the transfer account returned from this is from the credit key then the QIF file must be from the debit key and vice versa. """ if debit in self._files: key = credit elif credit in self._files: key = debit else: msg = ( "neither debit key ({0}) ".format(debit) + "or credit key ({0}) ".format(credit) + "has an associated QIF file" ) err = exception.create(KeyError, msg) raise err if key in self._accounts: return self._accounts[key] else: msg = "account key ({0}) ".format(key) + "does not have has an associated QIF account" err = exception.create(KeyError, msg) raise err
def _select_mailbox(self): """ Select a mailbox folder. """ result, response = self._imap.select(self._mailbox) if result == "NO": errmsg = _ERRMSG_INVALID_MAILBOX.format(self._mailbox) err = exception.create(ValueError, errmsg) raise err
def test__create__first_arg_is_message_preceded_by_type(self): """ Test that the first argument is input message preceded by <type>:. """ exception_type = ValueError input_message = "this is an error message" expected_message = ("{0}: {1}".format(exception_type.__name__, input_message)) err = exception.create(exception_type, input_message) actual_message = err.args[0] self.assertEqual(expected_message, actual_message)
def __init__(self, log, files, account_types, assets, liabilities, revenues, expenses): """ Parameters ---------- log : powl.log.Log Used to log. files : dict of powl.filesystem.File Map of account key to files. Every key in files must exist in either of assets, liabilities, revenues, or expenses. account_types : dict Map of account key to QIF account types. assets : dict Map of account key to Assets. liabilities : dict Map of account key to Liabilitess. revenues : dict Map of account key to Revenuess. expenses : dict Map of account key to Expensess. Notes ----- An account key is a string that maps to a QIF account. Multiple account key words can map to the same account. For example "ent" can map to "Expenses:Entertainment" and "entertainment" can also map to "Expenses:Entertainment". Raises ------ ValueError If a key is files does not have a key in any of assets, liabilities, revenues, or expenses. """ self._log = log self._files = files self._account_types = account_types self._assets = assets self._liabilities = liabilities self._revenues = revenues self._expenses = expenses self._accounts = dict( self._assets.items() + self._liabilities.items() + self._revenues.items() + self._expenses.items() ) for key, value in self._files.items(): if key not in self._accounts.keys(): msg = ( "account key ({0}) ".format(key) + "for file ({0}) ".format(value.filename) + "does not have has an associated QIF account" ) err = exception.create(ValueError, msg) raise err
def parse(self, string): """ Returns ------- powl.actiondata.BodyCompositionData Contains data to perform a body composition action. Raises ------ ValueError If mass or fat percentage is not a float. If a value for BodyCompositionData is missing. """ data = actiondata.BodyCompositionData() params = re.split(self._DELIMITER, string, self._MAX_SPLITS) if len(params) < self._NUM_PARAMS: msg = "not enough arguments from ({0})".format(string) err = exception.create(ValueError, msg) raise err mass = params[self._POSITION_MASS] fat_percentage = params[self._POSITION_FAT] try: data.mass = float(mass) except ValueError as err: msg = "mass ({0}) is not a number".format(mass) exception.add_message(err, msg) raise try: data.fat_percentage = float(fat_percentage) except ValueError as err: msg = "fat percentage ({0}) ".format(fat_percentage) + "is not a number" exception.add_message(err, msg) raise return data
def _format_amount(self, debit, amount): """ Convert amount to QIF format based on debit. Parameters ---------- debit : str Account key for the debit of a transaction. amount : str or float Amount of the transaction. Returns ------- str Formatted amount to use in QIF file. Raises ------ ValueError If amount cannot be converted to a float. KeyError If debit key is not an account. """ try: formatted_amount = "{0:.2f}".format(float(amount)) except ValueError as err: msg = "amount ({0}) cannot be converted to float".format(amount) exception.add_message(err, msg) raise if debit in self._expenses: # Amount should be negative. return "-" + formatted_amount elif debit in self._accounts: return formatted_amount else: msg = "account key ({0}) does not exist".format(debit) err = exception.create(KeyError, msg) raise err
def _assert_not_empty(self, value, errmsg): """ """ if not value: err = exception.create(ValueError, errmsg) raise err