Changeset - 677c99b565d8
[Not reviewed]
0 3 0
Brett Smith - 4 years ago 2020-06-03 22:51:48
brettcsmith@brettcsmith.org
accrual: Filter opening balance txn before main reporting.

So far we've been implicitly relying on this by the user passing search
terms that filter out the opening balance transaction. That will stop
happening with the aging report, so we need to do it ourselves.
3 files changed with 22 insertions and 8 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/reports/accrual.py
Show inline comments
...
 
@@ -489,24 +489,25 @@ def main(arglist: Optional[Sequence[str]]=None,
 
        config = configmod.Config()
 
        config.load_file()
 
    books_loader = config.books_loader()
 
    if books_loader is not None:
 
        entries, load_errors, _ = books_loader.load_fy_range(args.since)
 
    else:
 
        entries = []
 
        source = {
 
            'filename': str(config.config_file_path()),
 
            'lineno': 1,
 
        }
 
        load_errors = [Error(source, "no books to load in configuration", None)]
 
    filters.remove_opening_balance_txn(entries)
 
    postings = filter_search(data.Posting.from_entries(entries), args.search_terms)
 
    groups: PostGroups = dict(AccrualPostings.group_by_meta(postings, 'invoice'))
 
    groups = AccrualAccount.filter_paid_accruals(groups) or groups
 
    returncode = 0
 
    for error in load_errors:
 
        bc_printer.print_error(error, file=stderr)
 
        returncode |= ReturnFlag.LOAD_ERRORS
 
    for related in groups.values():
 
        for error in related.report_inconsistencies():
 
            bc_printer.print_error(error, file=stderr)
 
            returncode |= ReturnFlag.CONSISTENCY_ERRORS
 
    if args.report_type is None:
tests/books/accruals.beancount
Show inline comments
 
2020-01-01 open Assets:Checking
 
2020-01-01 open Assets:Receivable:Accounts
 
2020-01-01 open Expenses:FilingFees
 
2020-01-01 open Expenses:Services:Legal
 
2020-01-01 open Expenses:Travel
 
2020-01-01 open Income:Donations
 
2020-01-01 open Liabilities:Payable:Accounts
 
2020-01-01 open Equity:Funds:Opening
 

	
 
2020-03-01 * "Opening balances"
 
  Equity:Funds:Opening  -1000 USD
 
  Assets:Receivable:Accounts  6000 USD
 
  Liabilities:Payable:Accounts  -5000 USD
 

	
 
2020-03-05 * "EarlyBird" "Payment for receivable from previous FY"
 
  rt-id: "rt:40"
 
  invoice: "rt:40/400"
 
  Assets:Receivable:Accounts  -500 USD
 
  Assets:Checking  500 USD
 

	
 
2020-03-06 * "EarlyBird" "Payment for payment from previous FY"
 
  rt-id: "rt:44"
 
  invoice: "rt:44/440"
 
  Liabilities:Payable:Accounts  125 USD
 
  Assets:Checking  -125 USD
 

	
 
2020-03-30 * "EarlyBird" "Travel reimbursement"
 
  rt-id: "rt:490"
 
  invoice: "rt:490/4900"
 
  Liabilities:Payable:Accounts  -75 USD
 
  Expenses:Travel  75 USD
 

	
 
2020-04-30 ! "Vendor" "Travel reimbursement"
 
  rt-id: "rt:310"
 
  contract: "rt:310/3100"
 
  invoice: "FIXME"  ; still waiting on them to send it
 
  Liabilities:Payable:Accounts  -200 USD
 
  Expenses:Travel  200 USD
 

	
 
2020-05-05 * "DonorA" "Donation pledge"
 
  rt-id: "rt:505"
 
  invoice: "rt:505/5050"
 
  approval: "rt:505/5040"
 
  Income:Donations  -1000.00 USD
 
  Assets:Receivable:Accounts  1000.00 USD
 

	
 
2020-05-10 * "Lawyer" "April legal services"
 
  rt-id: "rt:510"
 
  invoice: "rt:510/5100"
 
  contract: "rt:510/4000"
 
  Expenses:Services:Legal  200.00 USD
tests/test_reports_accrual.py
Show inline comments
...
 
@@ -24,28 +24,33 @@ import re
 

	
 
import pytest
 

	
 
from . import testutil
 

	
 
from beancount import loader as bc_loader
 
from conservancy_beancount import data
 
from conservancy_beancount import rtutil
 
from conservancy_beancount.reports import accrual
 
from conservancy_beancount.reports import core
 

	
 
_accruals_load = bc_loader.load_file(testutil.test_path('books/accruals.beancount'))
 
ACCRUAL_TXNS = [
 
    entry for entry in _accruals_load[0]
 
    if hasattr(entry, 'narration')
 
    and entry.narration != 'Opening balances'
 
]
 
ACCRUALS_COUNT = sum(
 
    1
 
    for entry in _accruals_load[0]
 
    for post in getattr(entry, 'postings', ())
 
    for txn in ACCRUAL_TXNS
 
    for post in txn.postings
 
    if post.account.startswith(('Assets:Receivable:', 'Liabilities:Payable:'))
 
)
 

	
 
ACCOUNTS = [
 
    'Assets:Receivable:Accounts',
 
    'Assets:Receivable:Loans',
 
    'Liabilities:Payable:Accounts',
 
    'Liabilities:Payable:Vacation',
 
]
 

	
 
CONSISTENT_METADATA = [
 
    'contract',
...
 
@@ -65,32 +70,27 @@ class RTClient(testutil.RTClient):
 
        '505': [],
 
        '510': [
 
            ('4000', 'contract.pdf', 'application/pdf', '1.4m'),
 
            ('5100', 'invoice april.pdf', 'application/pdf', '1.5m'),
 
            ('5105', 'payment.png', 'image/png', '51.5k'),
 
            ('6100', 'invoice may.pdf', 'application/pdf', '1.6m'),
 
        ],
 
        '515': [],
 
        '520': [],
 
    }
 

	
 

	
 
@pytest.fixture
 
def accrual_entries():
 
    return copy.deepcopy(_accruals_load[0])
 

	
 
@pytest.fixture
 
def accrual_postings():
 
    entries = copy.deepcopy(_accruals_load[0])
 
    return data.Posting.from_entries(entries)
 
    return data.Posting.from_entries(copy.deepcopy(ACCRUAL_TXNS))
 

	
 
def check_link_regexp(regexp, match_s, first_link_only=False):
 
    assert regexp
 
    assert re.search(regexp, match_s)
 
    assert re.search(regexp, match_s + ' postlink')
 
    assert re.search(regexp, match_s + '0') is None
 
    assert re.search(regexp, '1' + match_s) is None
 
    end_match = re.search(regexp, 'prelink ' + match_s)
 
    if first_link_only:
 
        assert end_match is None
 
    else:
 
        assert end_match
0 comments (0 inline, 0 general)