# Path: auxi/core/objects.py
# class NamedObject(Object):
#     """
#     Base class for all auxi classes requiring a name and description.
# 
#     :param name: the object's name
#     :param description: the object's description
#     """
# 
#     def __init__(self, name, description=None):
#         self.name = name
#         self.description = description
# 
#     def _validate_params_(self, name, description):
#         # TODO: Enforce name format.
#         pass
# 
# Path: auxi/modelling/financial/des.py
# class AccountType(Enum):
#     """
#     Represents the type of general ledger account.
#     """
# 
#     asset = 1
#     equity = 2
#     expense = 3
#     liability = 4
#     revenue = 5
# 
# Path: auxi/modelling/financial/des.py
# class GeneralLedger(NamedObject):
#     """
#     Represents the account structure of a general ledger.
# 
#     :param name: The name.
#     :param structure: The general ledger structure.
#     :param description: The description.
#     """
# 
#     def __init__(self, name, structure, description=None):
#         super(GeneralLedger, self).__init__(name, description)
#         self.structure = structure
#         self.transactions = []
# 
#     def create_transaction(self, name, description=None,
#                            tx_date=datetime.min.date(),
#                            dt_account=None, cr_account=None,
#                            source=None, amount=0.00):
#         """
#         Create a transaction in the general ledger.
# 
#         :param name: The transaction's name.
#         :param description: The transaction's description.
#         :param tx_date: The date of the transaction.
#         :param cr_account: The transaction's credit account's name.
#         :param dt_account: The transaction's debit account's name.
#         :param source: The name of source the transaction originated from.
#         :param amount: The transaction amount.
# 
#         :returns: The created transaction.
#         """
# 
#         new_tx = Transaction(name, description, tx_date,
#                              dt_account, cr_account, source, amount)
#         self.transactions.append(new_tx)
#         return new_tx
# 
#     def transaction_list(self, start=datetime.min,
#                          end=datetime.max,
#                          format=ReportFormat.printout,
#                          component_path="",
#                          output_path=None):
#         """
#         Generate a transaction list report.
# 
#         :param start: The start date to generate the report for.
#         :param end: The end date to generate the report for.
#         :param format: The format of the report.
#         :param component_path: The path of the component to filter the report's
#           transactions by.
#         :param output_path: The path to the file the report is written to.
#           If None, then the report is not written to a file.
# 
#         :returns: The generated report.
#         """
# 
#         rpt = TransactionList(self, start, end, component_path, output_path)
#         return rpt.render(format)
# 
#     def balance_sheet(self, end=datetime.max,
#                       format=ReportFormat.printout, output_path=None):
#         """
#         Generate a transaction list report.
# 
#         :param end: The end date to generate the report for.
#         :param format: The format of the report.
#         :param output_path: The path to the file the report is written to.
#           If None, then the report is not written to a file.
# 
#         :returns: The generated report.
#         """
# 
#         rpt = BalanceSheet(self, end, output_path)
#         return rpt.render(format)
# 
#     def income_statement(self, start=datetime.min,
#                          end=datetime.max,
#                          format=ReportFormat.printout,
#                          component_path="",
#                          output_path=None):
#         """
#         Generate a transaction list report.
# 
#         :param start: The start date to generate the report for.
#         :param end: The end date to generate the report for.
#         :param format: The format of the report.
#         :param component_path: The path of the component to filter the report's
#           transactions by.
#         :param output_path: The path to the file the report is written to.
#           If None, then the report is not written to a file.
# 
#         :returns: The generated report.
#         """
# 
#         rpt = IncomeStatement(self, start, end, component_path, output_path)
#         return rpt.render(format)


from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from collections import OrderedDict
from auxi.core.objects import NamedObject
from auxi.modelling.financial.des import AccountType
from auxi.modelling.financial.des import GeneralLedger
    from auxi.modelling.business.structure_test import ActivityUnitTester
    from auxi.modelling.business.structure_test import ComponentUnitTester
    from auxi.modelling.business.structure_test import EntityUnitTester
    import unittest
                    else:
                        gross_profit_write_off_accs[cr_acc] = tx.amount
                elif dt_acc in sales_accs:
                    if dt_acc in gross_profit_write_off_accs:
                        gross_profit_write_off_accs[dt_acc] -= tx.amount
                    else:
                        gross_profit_write_off_accs[dt_acc] = -tx.amount

                elif cr_acc in cost_of_sales_accs:
                    if cr_acc in gross_profit_write_off_accs:
                        gross_profit_write_off_accs[cr_acc] += tx.amount
                    else:
                        gross_profit_write_off_accs[cr_acc] = tx.amount
                elif dt_acc in cost_of_sales_accs:
                    if dt_acc in gross_profit_write_off_accs:
                        gross_profit_write_off_accs[dt_acc] -= tx.amount
                    else:
                        gross_profit_write_off_accs[dt_acc] = -tx.amount

                elif cr_acc.account_type == AccountType.revenue:
                    if cr_acc in inc_summary_write_off_accs:
                        inc_summary_write_off_accs[cr_acc] += tx.amount
                    else:
                        inc_summary_write_off_accs[cr_acc] = tx.amount
                elif dt_acc.account_type == AccountType.revenue:
                    if dt_acc.account_type == AccountType.revenue:
                        inc_summary_write_off_accs[dt_acc] -= tx.amount
                    else:
                        inc_summary_write_off_accs[dt_acc] = -tx.amount


# Path: auxi/core/objects.py
# class NamedObject(Object):
#     """
#     Base class for all auxi classes requiring a name and description.
# 
#     :param name: the object's name
#     :param description: the object's description
#     """
# 
#     def __init__(self, name, description=None):
#         self.name = name
#         self.description = description
# 
#     def _validate_params_(self, name, description):
#         # TODO: Enforce name format.
#         pass
# 
# Path: auxi/modelling/financial/des.py
# class AccountType(Enum):
#     """
#     Represents the type of general ledger account.
#     """
# 
#     asset = 1
#     equity = 2
#     expense = 3
#     liability = 4
#     revenue = 5
# 
# Path: auxi/modelling/financial/des.py
# class GeneralLedger(NamedObject):
#     """
#     Represents the account structure of a general ledger.
# 
#     :param name: The name.
#     :param structure: The general ledger structure.
#     :param description: The description.
#     """
# 
#     def __init__(self, name, structure, description=None):
#         super(GeneralLedger, self).__init__(name, description)
#         self.structure = structure
#         self.transactions = []
# 
#     def create_transaction(self, name, description=None,
#                            tx_date=datetime.min.date(),
#                            dt_account=None, cr_account=None,
#                            source=None, amount=0.00):
#         """
#         Create a transaction in the general ledger.
# 
#         :param name: The transaction's name.
#         :param description: The transaction's description.
#         :param tx_date: The date of the transaction.
#         :param cr_account: The transaction's credit account's name.
#         :param dt_account: The transaction's debit account's name.
#         :param source: The name of source the transaction originated from.
#         :param amount: The transaction amount.
# 
#         :returns: The created transaction.
#         """
# 
#         new_tx = Transaction(name, description, tx_date,
#                              dt_account, cr_account, source, amount)
#         self.transactions.append(new_tx)
#         return new_tx
# 
#     def transaction_list(self, start=datetime.min,
#                          end=datetime.max,
#                          format=ReportFormat.printout,
#                          component_path="",
#                          output_path=None):
#         """
#         Generate a transaction list report.
# 
#         :param start: The start date to generate the report for.
#         :param end: The end date to generate the report for.
#         :param format: The format of the report.
#         :param component_path: The path of the component to filter the report's
#           transactions by.
#         :param output_path: The path to the file the report is written to.
#           If None, then the report is not written to a file.
# 
#         :returns: The generated report.
#         """
# 
#         rpt = TransactionList(self, start, end, component_path, output_path)
#         return rpt.render(format)
# 
#     def balance_sheet(self, end=datetime.max,
#                       format=ReportFormat.printout, output_path=None):
#         """
#         Generate a transaction list report.
# 
#         :param end: The end date to generate the report for.
#         :param format: The format of the report.
#         :param output_path: The path to the file the report is written to.
#           If None, then the report is not written to a file.
# 
#         :returns: The generated report.
#         """
# 
#         rpt = BalanceSheet(self, end, output_path)
#         return rpt.render(format)
# 
#     def income_statement(self, start=datetime.min,
#                          end=datetime.max,
#                          format=ReportFormat.printout,
#                          component_path="",
#                          output_path=None):
#         """
#         Generate a transaction list report.
# 
#         :param start: The start date to generate the report for.
#         :param end: The end date to generate the report for.
#         :param format: The format of the report.
#         :param component_path: The path of the component to filter the report's
#           transactions by.
#         :param output_path: The path to the file the report is written to.
#           If None, then the report is not written to a file.
# 
#         :returns: The generated report.
#         """
# 
#         rpt = IncomeStatement(self, start, end, component_path, output_path)
#         return rpt.render(format)


# Path: auxi/modelling/business/structure.py
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from collections import OrderedDict
from auxi.core.objects import NamedObject
from auxi.modelling.financial.des import AccountType
from auxi.modelling.financial.des import GeneralLedger
    from auxi.modelling.business.structure_test import ActivityUnitTester
    from auxi.modelling.business.structure_test import ComponentUnitTester
    from auxi.modelling.business.structure_test import EntityUnitTester
    import unittest

                    else:
                        gross_profit_write_off_accs[cr_acc] = tx.amount
                elif dt_acc in sales_accs:
                    if dt_acc in gross_profit_write_off_accs:
                        gross_profit_write_off_accs[dt_acc] -= tx.amount
                    else:
                        gross_profit_write_off_accs[dt_acc] = -tx.amount

                elif cr_acc in cost_of_sales_accs:
                    if cr_acc in gross_profit_write_off_accs:
                        gross_profit_write_off_accs[cr_acc] += tx.amount
                    else:
                        gross_profit_write_off_accs[cr_acc] = tx.amount
                elif dt_acc in cost_of_sales_accs:
                    if dt_acc in gross_profit_write_off_accs:
                        gross_profit_write_off_accs[dt_acc] -= tx.amount
                    else:
                        gross_profit_write_off_accs[dt_acc] = -tx.amount

                elif cr_acc.account_type == AccountType.revenue:
                    if cr_acc in inc_summary_write_off_accs:
                        inc_summary_write_off_accs[cr_acc] += tx.amount
                    else:
                        inc_summary_write_off_accs[cr_acc] = tx.amount
                elif dt_acc.account_type == AccountType.revenue:
                    if dt_acc.account_type == AccountType.revenue:
                        inc_summary_write_off_accs[dt_acc] -= tx.amount
                    else:
                        inc_summary_write_off_accs[dt_acc] = -tx.amount


                elif cr_acc.account_type == AccountType.expense: