balance_sheet: Add chart of accounts.
This commit is contained in:
		
							parent
							
								
									6159870681
								
							
						
					
					
						commit
						ee40b5b5c2
					
				
					 2 changed files with 52 additions and 2 deletions
				
			
		| 
						 | 
					@ -189,6 +189,15 @@ class Balances:
 | 
				
			||||||
            return prefix, -max_bal
 | 
					            return prefix, -max_bal
 | 
				
			||||||
        return sorted(class_bals, key=sortkey)
 | 
					        return sorted(class_bals, key=sortkey)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def iter_accounts(self, root: str) -> Iterable[data.Account]:
 | 
				
			||||||
 | 
					        start_date = self.period_range.start
 | 
				
			||||||
 | 
					        stop_date = self.period_range.stop
 | 
				
			||||||
 | 
					        for account in data.Account.iter_accounts(root):
 | 
				
			||||||
 | 
					            meta = account.meta
 | 
				
			||||||
 | 
					            if (meta.open_date < stop_date
 | 
				
			||||||
 | 
					                and (meta.close_date is None or meta.close_date > start_date)):
 | 
				
			||||||
 | 
					                yield account
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Report(core.BaseODS[Sequence[None], None]):
 | 
					class Report(core.BaseODS[Sequence[None], None]):
 | 
				
			||||||
    C_CASH = 'Cash'
 | 
					    C_CASH = 'Cash'
 | 
				
			||||||
| 
						 | 
					@ -233,6 +242,7 @@ class Report(core.BaseODS[Sequence[None], None]):
 | 
				
			||||||
        self.write_activities()
 | 
					        self.write_activities()
 | 
				
			||||||
        self.write_functional_expenses()
 | 
					        self.write_functional_expenses()
 | 
				
			||||||
        self.write_cash_flows()
 | 
					        self.write_cash_flows()
 | 
				
			||||||
 | 
					        self.write_chart_of_accounts()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def walk_classifications(self, cseq: Iterable[data.Account]) \
 | 
					    def walk_classifications(self, cseq: Iterable[data.Account]) \
 | 
				
			||||||
        -> Iterator[Tuple[str, Optional[data.Account]]]:
 | 
					        -> Iterator[Tuple[str, Optional[data.Account]]]:
 | 
				
			||||||
| 
						 | 
					@ -261,6 +271,7 @@ class Report(core.BaseODS[Sequence[None], None]):
 | 
				
			||||||
                    totals_prefix: Sequence[str]=(),
 | 
					                    totals_prefix: Sequence[str]=(),
 | 
				
			||||||
                    first_width: Union[float, str]=3,
 | 
					                    first_width: Union[float, str]=3,
 | 
				
			||||||
                    width: Union[float, str]=1.5,
 | 
					                    width: Union[float, str]=1.5,
 | 
				
			||||||
 | 
					                    title_fmt: str="DRAFT Statement of {sheet_name}",
 | 
				
			||||||
    ) -> None:
 | 
					    ) -> None:
 | 
				
			||||||
        header_cells: Sequence[odf.table.TableCell] = [
 | 
					        header_cells: Sequence[odf.table.TableCell] = [
 | 
				
			||||||
            odf.table.TableCell(),
 | 
					            odf.table.TableCell(),
 | 
				
			||||||
| 
						 | 
					@ -277,7 +288,7 @@ class Report(core.BaseODS[Sequence[None], None]):
 | 
				
			||||||
        start_date = self.balances.period_range.start.strftime(self.date_fmt)
 | 
					        start_date = self.balances.period_range.start.strftime(self.date_fmt)
 | 
				
			||||||
        self.add_row(
 | 
					        self.add_row(
 | 
				
			||||||
            self.multiline_cell([
 | 
					            self.multiline_cell([
 | 
				
			||||||
                f"DRAFT Statement of {sheet_name}",
 | 
					                title_fmt.format(sheet_name=sheet_name),
 | 
				
			||||||
                f"{start_date}—{self.period_name}",
 | 
					                f"{start_date}—{self.period_name}",
 | 
				
			||||||
            ], numbercolumnsspanned=self.col_count, stylename=self.style_header)
 | 
					            ], numbercolumnsspanned=self.col_count, stylename=self.style_header)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -554,6 +565,45 @@ class Report(core.BaseODS[Sequence[None], None]):
 | 
				
			||||||
            stylename=self.style_bottomline,
 | 
					            stylename=self.style_bottomline,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def write_chart_of_accounts(self) -> None:
 | 
				
			||||||
 | 
					        self.start_sheet(
 | 
				
			||||||
 | 
					            "Chart of Accounts",
 | 
				
			||||||
 | 
					            ["Account Name"], ["Classification"],
 | 
				
			||||||
 | 
					            totals_prefix=["Change During", "Year Ending"],
 | 
				
			||||||
 | 
					            title_fmt="{sheet_name}",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        # Widen text columns
 | 
				
			||||||
 | 
					        col_style = self.column_style(3.5)
 | 
				
			||||||
 | 
					        for col in self.sheet.childNodes[:2]:
 | 
				
			||||||
 | 
					            col.setAttribute('stylename', col_style)
 | 
				
			||||||
 | 
					        # Patch up header row text
 | 
				
			||||||
 | 
					        header_row = self.sheet.lastChild
 | 
				
			||||||
 | 
					        header_row.removeChild(header_row.firstChild)
 | 
				
			||||||
 | 
					        header_row.addElement(self.multiline_cell(
 | 
				
			||||||
 | 
					            ["Balance Ending", self.period_name],
 | 
				
			||||||
 | 
					            stylename=header_row.lastChild.getAttribute('stylename'),
 | 
				
			||||||
 | 
					        ))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for acct_root in ['Assets', 'Liabilities', 'Income', 'Expenses', 'Equity']:
 | 
				
			||||||
 | 
					            norm_func = core.normalize_amount_func(f'{acct_root}:Dummy')
 | 
				
			||||||
 | 
					            want_balance = acct_root not in EQUITY_ACCOUNTS
 | 
				
			||||||
 | 
					            self.add_row()
 | 
				
			||||||
 | 
					            for account in self.balances.iter_accounts(acct_root):
 | 
				
			||||||
 | 
					                period_bal = self.balances.total(account=account, period=Period.PERIOD)
 | 
				
			||||||
 | 
					                prior_bal = self.balances.total(account=account, period=Period.PRIOR)
 | 
				
			||||||
 | 
					                if want_balance:
 | 
				
			||||||
 | 
					                    total_bal = self.balances.total(account=account)
 | 
				
			||||||
 | 
					                    total_cell = self.balance_cell(norm_func(total_bal))
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    total_cell = odf.table.TableCell()
 | 
				
			||||||
 | 
					                self.add_row(
 | 
				
			||||||
 | 
					                    self.string_cell(account),
 | 
				
			||||||
 | 
					                    self.string_cell(account.meta.get('classification', '')),
 | 
				
			||||||
 | 
					                    self.balance_cell(norm_func(period_bal)),
 | 
				
			||||||
 | 
					                    self.balance_cell(norm_func(prior_bal)),
 | 
				
			||||||
 | 
					                    total_cell,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def parse_arguments(arglist: Optional[Sequence[str]]=None) -> argparse.Namespace:
 | 
					def parse_arguments(arglist: Optional[Sequence[str]]=None) -> argparse.Namespace:
 | 
				
			||||||
    parser = argparse.ArgumentParser(prog=PROGNAME)
 | 
					    parser = argparse.ArgumentParser(prog=PROGNAME)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								setup.py
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								setup.py
									
										
									
									
									
								
							| 
						 | 
					@ -5,7 +5,7 @@ from setuptools import setup
 | 
				
			||||||
setup(
 | 
					setup(
 | 
				
			||||||
    name='conservancy_beancount',
 | 
					    name='conservancy_beancount',
 | 
				
			||||||
    description="Plugin, library, and reports for reading Conservancy's books",
 | 
					    description="Plugin, library, and reports for reading Conservancy's books",
 | 
				
			||||||
    version='1.8.0',
 | 
					    version='1.8.1',
 | 
				
			||||||
    author='Software Freedom Conservancy',
 | 
					    author='Software Freedom Conservancy',
 | 
				
			||||||
    author_email='info@sfconservancy.org',
 | 
					    author_email='info@sfconservancy.org',
 | 
				
			||||||
    license='GNU AGPLv3+',
 | 
					    license='GNU AGPLv3+',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue