Changeset - d6821b13681b
[Not reviewed]
0 2 0
Brett Smith - 4 years ago 2020-06-28 13:43:44
brettcsmith@brettcsmith.org
fund: Fund report columns more closely match the audit report.
2 files changed with 23 insertions and 9 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/reports/fund.py
Show inline comments
...
 
@@ -104,69 +104,82 @@ class ODSReport(core.BaseODS[FundPosts, None]):
 
        return None
 

	
 
    def start_spreadsheet(self) -> None:
 
        self.use_sheet("With Breakdowns")
 
        for width in [2.5, 1.5, 1.2, 1.2, 1.2, 1.5, 1.2, 1.3, 1.2, 1.3]:
 
            col_style = self.column_style(width)
 
            self.sheet.addElement(odf.table.TableColumn(stylename=col_style))
 
        center_bold = self.merge_styles(self.style_centertext, self.style_bold)
 
        self.add_row(
 
            self.string_cell(
 
                "Fund", stylename=self.merge_styles(self.style_endtext, self.style_bold),
 
            ),
 
            self.multiline_cell(["Balance as of", self.start_date.isoformat()],
 
                                stylename=center_bold),
 
            self.string_cell("Income", stylename=center_bold),
 
            self.string_cell("Expenses", stylename=center_bold),
 
            self.multiline_cell(["Realized", "Gain/Loss"], stylename=center_bold),
 
            self.string_cell("Equity", stylename=center_bold),
 
            self.multiline_cell(["Balance as of", self.stop_date.isoformat()],
 
                                stylename=center_bold),
 
            self.multiline_cell(["Of Which", "Receivable"], stylename=center_bold),
 
            self.multiline_cell(["Of Which", "Prepaid Expenses"], stylename=center_bold),
 
            self.multiline_cell(["Of Which", "Payable"], stylename=center_bold),
 
            self.multiline_cell(["Of Which", "Unearned Income"], stylename=center_bold),
 
        )
 
        self.lock_first_row()
 
        self.add_row()
 
        self.add_row(self.string_cell(
 
            f"Fund Report From {self.start_date.isoformat()} To {self.stop_date.isoformat()}",
 
            stylename=center_bold,
 
            numbercolumnsspanned=6,
 
        ))
 
        self.add_row()
 

	
 
    def end_spreadsheet(self) -> None:
 
        sheet = self.copy_element(self.sheet)
 
        sheet.setAttribute('name', 'Fund Report')
 
        row_qname = sheet.lastChild.qname
 
        row_qname = odf.table.TableRow().qname
 
        skip_rows: List[int] = []
 
        report_threshold = Decimal('.5')
 
        first_row = True
 
        for index, row in enumerate(sheet.childNodes):
 
            row.childNodes = row.childNodes[:6]
 
            if len(row.childNodes) < 6:
 
                continue
 
            row.childNodes = [*row.childNodes[:4], row.childNodes[5]]
 
            if row.qname != row_qname:
 
                pass
 
            elif first_row:
 
                ref_child = row.childNodes[2]
 
                stylename = ref_child.getAttribute('stylename')
 
                row.insertBefore(self.string_cell(
 
                    "Additions", stylename=stylename,
 
                ), ref_child)
 
                row.insertBefore(self.multiline_cell(
 
                    ["Releases from", "Restrictions"], stylename=stylename,
 
                ), ref_child)
 
                del row.childNodes[4:6]
 
                first_row = False
 
            # Filter out fund rows that don't have anything reportable.
 
            if (row.qname == row_qname
 
                # len(childNodes) makes sure this isn't a header/spacer row.
 
                and len(row.childNodes) == 6
 
                and not any(
 
            elif not any(
 
                    # Multiple childNodes means it's a multi-currency balance.
 
                    len(cell.childNodes) > 1
 
                    # Some column has to round up to 1 to be reportable.
 
                    or (cell.getAttribute('valuetype') == 'currency'
 
                        and Decimal(cell.getAttribute('value')) >= report_threshold)
 
                    for cell in row.childNodes
 
            )):
 
            ):
 
                skip_rows.append(index)
 
        for index in reversed(skip_rows):
 
            del sheet.childNodes[index]
 
        self.lock_first_row(sheet)
 
        self.document.spreadsheet.insertBefore(sheet, self.sheet)
 

	
 
    def _row_balances(self, accounts_map: AccountsMap) -> Iterable[core.Balance]:
 
        acct_order = ['Income', 'Expenses', 'Equity']
 
        key_order = [core.OPENING_BALANCE_NAME, *acct_order, core.ENDING_BALANCE_NAME]
 
        balances: Dict[str, core.Balance] = {key: core.MutableBalance() for key in key_order}
 
        for acct_s, balance in core.account_balances(accounts_map, acct_order):
 
            if acct_s in balances:
 
                balances[acct_s] = balance
 
            else:
 
                acct_root, _, _ = acct_s.partition(':')
 
                balances[acct_root] += balance
tests/test_reports_fund.py
Show inline comments
...
 
@@ -172,33 +172,34 @@ def check_ods_sheet(sheet, account_balances, *, full):
 
            for key, balances in account_balances.items()
 
            if key != 'Conservancy' and any(v >= .5 for v in balances.values())
 
        }
 
    for row in itertools.islice(sheet.getElementsByType(odf.table.TableRow), 4, None):
 
        cells = iter(testutil.ODSCell.from_row(row))
 
        try:
 
            fund = next(cells).firstChild.text
 
        except (AttributeError, StopIteration):
 
            continue
 
        try:
 
            balances = account_bals.pop(fund)
 
        except KeyError:
 
            pytest.fail(f"report included unexpected fund {fund}")
 
        check_cell_balance(next(cells), balances['opening'])
 
        check_cell_balance(next(cells), balances['Income'])
 
        check_cell_balance(next(cells), -balances['Expenses'])
 
        check_cell_balance(next(cells), balances['Equity:Realized'])
 
        if full:
 
            check_cell_balance(next(cells), balances['Equity:Realized'])
 
        check_cell_balance(next(cells), sum(balances[key] for key in [
 
            'opening', 'Income', 'Expenses', 'Equity:Realized',
 
        ]))
 
        if full:
 
            check_cell_balance(next(cells), balances['Assets:Receivable'])
 
            check_cell_balance(next(cells), balances['Assets:Prepaid'])
 
            check_cell_balance(next(cells), balances['Liabilities:Payable'])
 
            check_cell_balance(next(cells), balances['Liabilities'])
 
        assert next(cells, None) is None
 
    assert not account_bals, "did not see all funds in report"
 

	
 
def check_ods_report(ods, start_date, stop_date):
 
    account_bals = collections.OrderedDict((key, {
 
        'opening': Decimal(amount),
 
        'Income': Decimal(0),
 
        'Expenses': Decimal(0),
0 comments (0 inline, 0 general)