Example #1
0
    def __init__(self,
                 account,
                 currency='CAD',
                 basename=None,
                 first_day=None,
                 filename_regexp=None,
                 account_types=None):
        """Create a new importer for the given account.

        Args:
          account: An account string, the account to associate to the files.
          account_types: An AccountTypes object or None to use the default ones.
          basename: An optional string, the name of the new files.
          currency: A string, the currency for all extracted transactions.
          filename_regexp: A regular expression string used to match the
            basename (no path) of the target file.
          first_day: An int in [1,28]; the first day of the statement/billing
            period or None. If None, the file date will be the date of the
            last extracted entry; otherwise, it will be the date of the end
            of the monthly period containing the last extracted entry.
            Also, if a balance directive can be generated, if None, the balance
            directive will be set to the day following the date of the last
            extracted entry; otherwise, it will be set to the day following the
            end of the statement period.
        """
        self.filename_re = re.compile(filename_regexp or self.filename_regexp)
        self.account = account
        self.currency = currency.upper()
        self.basename = basename
        self.first_day = first_day
        self.account_sign = atypes.get_account_sign(account, account_types)
Example #2
0
    def __init__(self, account, currency='CAD', basename=None,
                 first_day=None, filename_regexp=None, account_types=None):
        """Create a new importer for the given account.

        Args:
          account: An account string, the account to associate to the files.
          account_types: An AccountTypes object or None to use the default ones.
          basename: An optional string, the name of the new files.
          currency: A string, the currency for all extracted transactions.
          filename_regexp: A regular expression string used to match the
            basename (no path) of the target file.
          first_day: An int in [1,28]; the first day of the statement/billing
            period or None. If None, the file date will be the date of the
            last extracted entry; otherwise, it will be the date of the end
            of the monthly period containing the last extracted entry.
            Also, if a balance directive can be generated, if None, the balance
            directive will be set to the day following the date of the last
            extracted entry; otherwise, it will be set to the day following the
            end of the statement period.
        """
        self.filename_re = re.compile(filename_regexp or self.filename_regexp)
        self.account = account
        self.currency = currency.upper()
        self.basename = basename
        self.first_day = first_day
        self.account_sign = atypes.get_account_sign(account, account_types)
 def test_get_account_sign(self):
     for account_name, expected in [
         ("Assets:US:RBS:Savings", +1),
         ("Liabilities:US:RBS:MortgageLoan", -1),
         ("Equity:Opening-Balances", -1),
         ("Income:US:ETrade:Dividends", -1),
         ("Expenses:Toys:Computer", +1),
     ]:
         self.assertEqual(expected,
                          account_types.get_account_sign(account_name))
Example #4
0
    def get_account_sign(self, account_name):
        """Get account sign.

        Arguments:
            account_name: An account name.

        Returns:
            The sign of the given account, +1 for an assets or expenses
            account, -1 otherwise.
        """
        return get_account_sign(account_name, self.account_types)
Example #5
0
    def get_account_sign(self, account_name):
        """Get account sign.

        Arguments:
            account_name: An account name.

        Returns:
            The sign of the given account, +1 for an assets or expenses
            account, -1 otherwise.
        """
        return get_account_sign(account_name, self.account_types)
Example #6
0
def add_ira_contribs(entries, options_map, config):
    """Add legs for 401k employer match contributions.

    See module docstring for an example configuration.

    Args:
      entries: a list of entry instances
      options_map: a dict of options parsed from the file
      config: A configuration string, which is intended to be a Python dict
        mapping match-accounts to a pair of (negative-account, position-account)
        account names.
    Returns:
      A tuple of entries and errors.
    """
    # Parse and extract configuration values.
    config_obj = eval(config, {}, {})
    if not isinstance(config_obj, dict):
        raise RuntimeError(
            "Invalid plugin configuration: should be a single dict.")

    currency = config_obj.pop('currency', 'UNKNOWN')
    flag = config_obj.pop('flag', None)
    account_transforms = config_obj.pop('accounts', {})

    new_entries = []
    for entry in entries:
        if isinstance(entry, data.Transaction):
            orig_entry = entry
            for posting in entry.postings:
                if (posting.account in account_transforms and posting.position
                        and (account_types.get_account_sign(posting.account) *
                             posting.position.number) > 0):

                    # Get the new account legs to insert.
                    neg_account, pos_account = account_transforms[
                        posting.account]
                    assert posting.position.lot.cost is None

                    # Insert income/expense entries for 401k.
                    entry = add_postings(
                        entry,
                        amount.Amount(abs(posting.position.number), currency),
                        neg_account.format(year=entry.date.year),
                        pos_account.format(year=entry.date.year), flag)

            if DEBUG and orig_entry is not entry:
                printer.print_entry(orig_entry)
                printer.print_entry(entry)

        new_entries.append(entry)

    return new_entries, []
Example #7
0
 def get_account_sign(self, account_name):
     """Get account sign."""
     return get_account_sign(account_name, self.account_types)
Example #8
0
 def get_account_sign(self, account_name):
     return get_account_sign(account_name, self.account_types)
Example #9
0
 def treemap_data(self, account_name):
     return {
         'label': account_name,
         'balances': self.balances(account_name),
         'modifier': get_account_sign(account_name, self.account_types),
     }
Example #10
0
def possign(context, x, account):
    """Correct sign of an Amount based on the usual balance of associated account."""
    sign = account_types.get_account_sign(account, context.account_types)
    return x if sign >= 0 else -x
Example #11
0
 def treemap_data(self, account_name, begin_date=None, end_date=None):
     return {
         'label': account_name,
         'balances': self.balances(account_name, begin_date, end_date),
         'modifier': get_account_sign(account_name, self.account_types),
     }
Example #12
0
def add_ira_contribs(entries, options_map, config_str):
    """Add legs for 401k employer match contributions.

    See module docstring for an example configuration.

    Args:
      entries: a list of entry instances
      options_map: a dict of options parsed from the file
      config_str: A configuration string, which is intended to be a Python dict
        mapping match-accounts to a pair of (negative-account, position-account)
        account names.
    Returns:
      A tuple of entries and errors.
    """
    # Parse and extract configuration values.
    # FIXME: Use ast.literal_eval() here; you need to convert this code and the getters.
    # FIXME: Also, don't raise a RuntimeError, return an error object; review
    # this for all the plugins.
    # FIXME: This too is temporary.
    # pylint: disable=eval-used
    config_obj = eval(config_str, {}, {})
    if not isinstance(config_obj, dict):
        raise RuntimeError(
            "Invalid plugin configuration: should be a single dict.")

    # Currency of the inserted postings.
    currency = config_obj.pop('currency', 'UNKNOWN')

    # Flag to attach to the inserted postings.
    insert_flag = config_obj.pop('flag', None)

    # A dict of account names that trigger the insertion of postings to pairs of
    # inserted accounts when triggered.
    accounts = config_obj.pop('accounts', {})

    # Convert the key in the accounts configuration for matching.
    account_transforms = {}
    for key, config in accounts.items():
        if isinstance(key, str):
            flag = None
            account = key
        else:
            assert isinstance(key, tuple)
            flag, account = key
        account_transforms[account] = (flag, config)

    new_entries = []
    for entry in entries:
        if isinstance(entry, data.Transaction):
            orig_entry = entry
            for posting in entry.postings:
                if (posting.units is not MISSING
                        and (posting.account in account_transforms)
                        and (account_types.get_account_sign(posting.account) *
                             posting.units.number > 0)):

                    # Get the new account legs to insert.
                    required_flag, (
                        neg_account,
                        pos_account) = account_transforms[posting.account]
                    assert posting.cost is None

                    # Check required flag if present.
                    if (required_flag is None or
                        (required_flag and required_flag == posting.flag)):
                        # Insert income/expense entries for 401k.
                        entry = add_postings(
                            entry,
                            amount.Amount(abs(posting.units.number), currency),
                            neg_account.format(year=entry.date.year),
                            pos_account.format(year=entry.date.year),
                            insert_flag)

            if DEBUG and orig_entry is not entry:
                printer.print_entry(orig_entry)
                printer.print_entry(entry)

        new_entries.append(entry)

    return new_entries, []
Example #13
0
 def get_account_sign(self, account_name):
     return get_account_sign(account_name, self.account_types)