def setUp(self): self.structure = GeneralLedgerStructure("NameA", description="DescriptionA") self.structure["Retained Income"].create_account( "TestA", description="TestA_Desc", number="010") self.object = GeneralLedger("NameA", self.structure, description="DescriptionA")
def __init__(self, name, gl_structure, description=None): self.gl = GeneralLedger("General Ledger", gl_structure, description="General Ledger") self._parent_path = "" self.path = name self.components = [] self.negative_income_tax_total = 0 self._prev_year_end_datetime = datetime.min self._curr_year_end_datetime = datetime.min self._exec_year_end_datetime = datetime.min self.period_count = -1 super(Entity, self).__init__(name, description=description)
def setUp(self): gls = Gls("NameA") self.gl = GeneralLedger("NameA", gls) self.object = TransactionList( data_source=self.gl, start=datetime(2016, 4, 1), end=datetime(2016, 8, 1), output_path=None) self.gl.create_transaction( "tx1", description='1', tx_date=datetime(2016, 2, 1), dt_account="Bank\Default1", cr_account="Sales\Default1", source="test1", amount=1001) self.gl.create_transaction( "tx2", description='2', tx_date=datetime(2016, 3, 1), dt_account="Bank\Default2", cr_account="Sales\Default2", source="test2", amount=1002) self.gl.create_transaction( "tx3", description='3', tx_date=datetime(2016, 4, 2), dt_account="Bank\Default3", cr_account="Sales\Default3", source="test3", amount=1003) self.gl.create_transaction( "tx4", description='4', tx_date=datetime(2016, 5, 1), dt_account="Bank\Default4", cr_account="Sales\Default4", source="test4", amount=1004) self.gl.create_transaction( "tx5", description='5', tx_date=datetime(2016, 9, 1), dt_account="Bank\Default5", cr_account="Sales\Default5", source="test5", amount=1005)
class GeneralLedgerUnitTester(unittest.TestCase): """ Tester for the auxi.modelling.financial.des.GeneralLedger class. """ def setUp(self): self.structure = GeneralLedgerStructure("NameA", description="DescriptionA") self.structure["Retained Income"].create_account( "TestA", description="TestA_Desc", number="010") self.object = GeneralLedger("NameA", self.structure, description="DescriptionA") def test_constructor(self): self.assertEqual(self.object.name, "NameA") self.assertEqual(self.object.description, "DescriptionA") self.assertEqual(self.structure, self.object.structure) def test_create_transaction(self): new_tx = self.object.create_transaction("TestA", description="TestA_Desc", tx_date=datetime(2016, 2, 1).date(), dt_account="Bank", cr_account="Sales", source="Peanut Sales", amount=20.00) tx_list = self.object.transactions self.assertEqual(new_tx.name, tx_list[0].name) self.assertEqual(new_tx.tx_date, tx_list[0].tx_date) self.assertEqual(new_tx.dt_account, tx_list[0].dt_account) self.assertEqual(new_tx.cr_account, tx_list[0].cr_account) self.assertEqual(new_tx.source, tx_list[0].source) self.assertEqual(new_tx.amount, tx_list[0].amount)
def __init__(self, name, gl_structure, description=None): self.gl = GeneralLedger( "General Ledger", gl_structure, description="General Ledger") self._parent_path = "" self.path = name self.components = [] self.negative_income_tax_total = 0 self._prev_year_end_datetime = datetime.min self._curr_year_end_datetime = datetime.min self._exec_year_end_datetime = datetime.min self.period_count = -1 super(Entity, self).__init__(name, description=description)
def test_run(self): """ Test that the activity run method creates a transaction with an amount of 5000. """ structure = GeneralLedgerStructure("NameA", description="DescriptionA") gl = GeneralLedger("NameA", structure, description="DescriptionA") clock = Clock("NameA", start_datetime=datetime(2016, 1, 1)) clock.tick() clock.tick() self.object.prepare_to_run(clock, 20) self.object.run(clock, gl) self.assertEqual(len(gl.transactions), 1) self.assertEqual(gl.transactions[0].amount, 5000)
def test_run(self): """ Test that the component runs its activities. """ # Set up the general ledger so that an activity can create a # transaction. structure = GeneralLedgerStructure("NameA", description="DescriptionA") gl = GeneralLedger("NameA", structure, description="DescriptionA") # Prepare the component for a run. Tick the clock to the correct place # for the activity to create a transaction. clock = Clock("NameA", start_datetime=datetime(2016, 1, 1)) clock.tick() clock.tick() self.object.prepare_to_run(clock, 20) self.object.run(clock, gl) # If the activity has been run, then a transaction should have # been generated. self.assertEqual(len(gl.transactions), 1)
def setUp(self): self.gl_structure = GeneralLedgerStructure("NameA", description="DescriptionA") self.gl_structure["Sales"].create_account("Default", number="0000") self.gl = GeneralLedger("NameA", self.gl_structure, description="DescriptionA") self.object = Component("ComponentA", self.gl, description="DescriptionA") # Set up the needed objects self.object.create_component("ComponentA1", description="ca1") self.object.create_component("ComponentA2", description="ca2") self.basic_activity = BasicActivity("BasicActivityA", description="DescriptionA", dt_account="Bank/Default", cr_account="Sales/Default", amount=5000, start=datetime(2016, 2, 1), end=datetime(2017, 2, 1), interval=3) self.object["ComponentA1"].add_activity(self.basic_activity)
class GeneralLedgerUnitTester(unittest.TestCase): """ Tester for the auxi.modelling.financial.des.GeneralLedger class. """ def setUp(self): self.structure = GeneralLedgerStructure("NameA", description="DescriptionA") self.structure["Retained Income"].create_account( "TestA", description="TestA_Desc", number="010") self.object = GeneralLedger("NameA", self.structure, description="DescriptionA") def test_constructor(self): self.assertEqual(self.object.name, "NameA") self.assertEqual(self.object.description, "DescriptionA") self.assertEqual(self.structure, self.object.structure) def test_create_transaction(self): new_tx = self.object.create_transaction( "TestA", description="TestA_Desc", tx_date=datetime(2016, 2, 1).date(), dt_account="Bank", cr_account="Sales", source="Peanut Sales", amount=20.00) tx_list = self.object.transactions self.assertEqual(new_tx.name, tx_list[0].name) self.assertEqual(new_tx.tx_date, tx_list[0].tx_date) self.assertEqual(new_tx.dt_account, tx_list[0].dt_account) self.assertEqual(new_tx.cr_account, tx_list[0].cr_account) self.assertEqual(new_tx.source, tx_list[0].source) self.assertEqual(new_tx.amount, tx_list[0].amount)
def setUp(self): self.gl_structure = GeneralLedgerStructure( "GL Structure", description="General Ledger Structure") self.gl_structure["Account Payable"].create_account( "Capital Loan", "0000") self.gl_structure["Expense"].create_account("Interest Expense", "0000") self.gl = GeneralLedger("GL", self.gl_structure, description="General Ledger") self.clock = Clock("NameA", start_datetime=datetime(2016, 2, 1)) self.object = BasicLoanActivity( "Capital Loan", bank_account="Bank/Default", loan_account="Account Payable/Capital Loan", interest_account="Expense/Interest Expense", amount=180000, interest_rate=0.15, start=datetime(2016, 2, 1), duration=36, interval=1, description="Loan for Capital")
class Entity(NamedObject): """ Represents an entity class. An entity consists of business components e.g. Sales department. It executes its components and performs financial year end transcations. :param name: The name. :param gl_structure: The general ledger structure the entity's general ledger will be initialized with. :param description: The description. :param period_count: The number of periods the entity should be run for. """ def __init__(self, name, gl_structure, description=None): self.gl = GeneralLedger( "General Ledger", gl_structure, description="General Ledger") self._parent_path = "" self.path = name self.components = [] self.negative_income_tax_total = 0 self._prev_year_end_datetime = datetime.min self._curr_year_end_datetime = datetime.min self._exec_year_end_datetime = datetime.min self.period_count = -1 super(Entity, self).__init__(name, description=description) def __getitem__(self, key): return [c for c in self.components if c.name == key][0] def set_parent_path(self, value): """ Set the parent path and the path from the new parent path. :param value: The path to the object's parent """ self._parent_path = value self.path = value + r'/' + self.name self._update_childrens_parent_path() def _update_childrens_parent_path(self): for c in self.components: c.set_parent_path(self.path) @property def name(self): return self._name @name.setter def name(self, value): self._name = value self.path = self._parent_path + r'/' + self.name self._update_childrens_parent_path() def create_component(self, name, description=None): """ Create a component in the business entity. :param name: The component's name. :param description: The component's description. :returns: The created component. """ new_comp = Component(name, self.gl, description=description) new_comp.set_parent_path(self.path) self.components.append(new_comp) return new_comp def remove_component(self, name): """ Remove a component from the entity. :param name: The name of the component to remove. """ component_to_remove = None for c in self.components: if c.name == name: component_to_remove = c if component_to_remove is not None: self.components.remove(component_to_remove) def prepare_to_run(self, clock, period_count): """ Prepare the entity for execution. :param clock: The clock containing the execution start time and execution period information. :param period_count: The total amount of periods this activity will be requested to be run for. """ self.period_count = period_count self._exec_year_end_datetime = clock.get_datetime_at_period_ix( period_count) self._prev_year_end_datetime = clock.start_datetime self._curr_year_end_datetime = clock.start_datetime + relativedelta( years=1) # Remove all the transactions del self.gl.transactions[:] for c in self.components: c.prepare_to_run(clock, period_count) self.negative_income_tax_total = 0 def run(self, clock): """ Execute the entity at the current clock cycle. :param clock: The clock containing the current execution time and period information. """ if clock.timestep_ix >= self.period_count: return for c in self.components: c.run(clock, self.gl) self._perform_year_end_procedure(clock) def _perform_year_end_procedure(self, clock): if clock.get_datetime() >= self._curr_year_end_datetime\ or clock.timestep_ix == self.period_count: gls = self.gl.structure year_start_date = self._prev_year_end_datetime year_end_date = self._curr_year_end_datetime + \ timedelta(seconds=-1) self._prev_year_end_datetime = self._curr_year_end_datetime self._curr_year_end_datetime += relativedelta(years=1) if self._curr_year_end_datetime > self._exec_year_end_datetime: self._curr_year_end_datetime = self._exec_year_end_datetime gross_profit_write_off_accs = OrderedDict() inc_summary_write_off_accs = OrderedDict() sales_accs = gls.get_account_decendants(gls._acci_sales_) cost_of_sales_accs = gls.get_account_decendants(gls._acci_cos_) year_taxes = [] for tx in self.gl.transactions: if tx.tx_date >= year_start_date and\ tx.tx_date <= year_end_date: year_taxes.append(tx) for tx in year_taxes: cr_acc = gls.get_account(tx.cr_account) dt_acc = gls.get_account(tx.dt_account) if cr_acc in 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 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: 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.expense: if dt_acc in inc_summary_write_off_accs: inc_summary_write_off_accs[dt_acc] += tx.amount else: inc_summary_write_off_accs[dt_acc] = tx.amount inc_sum = self._perform_year_end_gross_profit_and_income_summary( year_end_date, gross_profit_write_off_accs, inc_summary_write_off_accs) inc_sum = self._perform_year_end_income_tax( year_end_date, inc_sum) self._perform_year_end_retained_earnings( year_end_date, inc_sum) def _perform_year_end_gross_profit_and_income_summary( self, year_end_datetime, gross_profit_write_off_accounts, income_summary_write_off_accounts): gls = self.gl.structure gross_profit = self._perform_year_end_gross_profit( year_end_datetime, gross_profit_write_off_accounts) income_summary_amount = self._perform_year_end_income_summary( year_end_datetime, gross_profit, income_summary_write_off_accounts) def create_tx(dt_account, cr_account): tx_name = "Settle the '" + gls._acci_gross_prof_.path +\ "' Account" new_tx = self.gl.create_transaction( tx_name, description=tx_name, tx_date=year_end_datetime, dt_account=dt_account, cr_account=cr_account, source=self.path, amount=abs(gross_profit)) new_tx.is_closing_cr_account = True if gross_profit > 0: create_tx(gls._acci_gross_prof_.path, gls._acci_inc_sum_.path) elif gross_profit < 0: create_tx(gls._acci_inc_sum_.path, gls._acci_gross_prof_.path) return income_summary_amount def _perform_year_end_gross_profit(self, year_end_datetime, gross_profit_write_off_accounts): gls = self.gl.structure gross_profit = 0 for acc, amount in gross_profit_write_off_accounts.items(): def create_tx(dt_account, cr_account): tx_name = "Settle the '" + acc.path + "' Account" new_tx = self.gl.create_transaction( tx_name, description=tx_name, tx_date=year_end_datetime, dt_account=dt_account, cr_account=cr_account, source=self.path, amount=abs(amount)) new_tx.is_closing_cr_account = True gross_profit += amount if amount > 0: create_tx(gls._acci_gross_prof_.path, acc.path) elif amount < 0: create_tx(acc.path, gls._acci_gross_prof_.path) return gross_profit def _perform_year_end_income_summary(self, year_end_datetime, gross_profit, income_summary_write_off_accounts): gls = self.gl.structure income_summary_amount = gross_profit for acc, amount in income_summary_write_off_accounts.items(): def create_tx(dt_account, cr_account): tx_name = "Settle the '" + acc.path + "' Account" new_tx = self.gl.create_transaction( tx_name, description=tx_name, tx_date=year_end_datetime, dt_account=dt_account, cr_account=cr_account, source=self.path, amount=abs(amount)) new_tx.is_closing_cr_account = True if amount > 0: if acc.account_type == AccountType.expense: income_summary_amount -= amount create_tx(gls._acci_inc_sum_.path, acc.path) else: income_summary_amount += amount create_tx(acc.path, gls._acci_inc_sum_.path) elif amount < 0: if acc.account_type == AccountType.expense: income_summary_amount -= amount create_tx(acc.path, gls._acci_inc_sum_.path) else: income_summary_amount += amount create_tx(gls._acci_inc_sum_.path, acc.path) return income_summary_amount def _perform_year_end_income_tax(self, year_end_datetime, income_summary_amount): return income_summary_amount def _perform_year_end_retained_earnings(self, year_end_datetime, income_summary_amount): def create_tx(dt_account, cr_account): tx_name = "Settle the '" + gls._acci_inc_sum_.path +\ "' Account, adjust Retained Earnings accordingly." new_tx = self.gl.create_transaction( tx_name, description=tx_name, tx_date=year_end_datetime, dt_account=dt_account, cr_account=cr_account, source=self.path, amount=income_summary_amount) new_tx.is_closing_cr_account = True gls = self.gl.structure if income_summary_amount > 0: create_tx(gls._acci_inc_sum_.path, gls._accb_ret_earnings_acc_.path) elif income_summary_amount < 0: create_tx(gls._accb_ret_earnings_acc_.path, gls._acci_inc_sum_.path)
class TransactionListUnitTester(unittest.TestCase): """ Tester for the auxi.modelling.financial.reporting.TransactionList class. """ def setUp(self): gls = Gls("NameA") self.gl = GeneralLedger("NameA", gls) self.object = TransactionList( data_source=self.gl, start=datetime(2016, 4, 1), end=datetime(2016, 8, 1), output_path=None) self.gl.create_transaction( "tx1", description='1', tx_date=datetime(2016, 2, 1), dt_account="Bank\Default1", cr_account="Sales\Default1", source="test1", amount=1001) self.gl.create_transaction( "tx2", description='2', tx_date=datetime(2016, 3, 1), dt_account="Bank\Default2", cr_account="Sales\Default2", source="test2", amount=1002) self.gl.create_transaction( "tx3", description='3', tx_date=datetime(2016, 4, 2), dt_account="Bank\Default3", cr_account="Sales\Default3", source="test3", amount=1003) self.gl.create_transaction( "tx4", description='4', tx_date=datetime(2016, 5, 1), dt_account="Bank\Default4", cr_account="Sales\Default4", source="test4", amount=1004) self.gl.create_transaction( "tx5", description='5', tx_date=datetime(2016, 9, 1), dt_account="Bank\Default5", cr_account="Sales\Default5", source="test5", amount=1005) def test__generate_table_(self): table = self.object._generate_table_() self.assertEqual(table[0], [ "Date", "Source", "Tx Name", "Debit Account", "Credit Account", "Amount", "Description"]) # There should be 4 rows, 1 for the header, 2 for transactions # and 1 for the 'Total' column. self.assertEqual(len(table), 4) # The first 2 and last to transactions # in the GL falls outside the request start and end date. Thus, only # the 3rd and 4th transactions should appear in the report. # Test that the transaction names are correct. self.assertEqual(table[1][2], "tx3") self.assertEqual(table[2][2], "tx4") # Test that the transaction amounts are correct. self.assertEqual(table[1][5], '1003.00') self.assertEqual(table[2][5], '1004.00') # Test that the transaction sources are correct. self.assertEqual(table[1][1], "test3") self.assertEqual(table[2][1], "test4") # Test that the transaction dates are correct. self.assertEqual(table[1][0], datetime(2016, 4, 2)) self.assertEqual(table[2][0], datetime(2016, 5, 1)) # Test that the transaction dt accounts are correct. self.assertEqual(table[1][3], "Bank\Default3") self.assertEqual(table[2][3], "Bank\Default4") # Test that the transaction dt accounts are correct. self.assertEqual(table[1][4], "Sales\Default3") self.assertEqual(table[2][4], "Sales\Default4") # Test that the transaction descriptions are correct. self.assertEqual(table[1][6], "3") self.assertEqual(table[2][6], "4")
class Entity(NamedObject): """ Represents an entity class. An entity consists of business components e.g. Sales department. It executes its components and performs financial year end transactions. :param name: The name. :param gl_structure: The general ledger structure the entity's general ledger will be initialized with. :param description: The description. :param period_count: The number of periods the entity should be run for. """ def __init__(self, name, gl_structure, description=None): self.gl = GeneralLedger("General Ledger", gl_structure, description="General Ledger") self._parent_path = "" self.path = name self.components = [] self.negative_income_tax_total = 0 self._prev_year_end_datetime = datetime.min self._curr_year_end_datetime = datetime.min self._exec_year_end_datetime = datetime.min self.period_count = -1 super(Entity, self).__init__(name, description=description) def __getitem__(self, key): return [c for c in self.components if c.name == key][0] def set_parent_path(self, value): """ Set the parent path and the path from the new parent path. :param value: The path to the object's parent """ self._parent_path = value self.path = value + r'/' + self.name self._update_childrens_parent_path() def _update_childrens_parent_path(self): for c in self.components: c.set_parent_path(self.path) @property def name(self): return self._name @name.setter def name(self, value): self._name = value self.path = self._parent_path + r'/' + self.name self._update_childrens_parent_path() def create_component(self, name, description=None): """ Create a component in the business entity. :param name: The component's name. :param description: The component's description. :returns: The created component. """ new_comp = Component(name, self.gl, description=description) new_comp.set_parent_path(self.path) self.components.append(new_comp) return new_comp def remove_component(self, name): """ Remove a component from the entity. :param name: The name of the component to remove. """ component_to_remove = None for c in self.components: if c.name == name: component_to_remove = c if component_to_remove is not None: self.components.remove(component_to_remove) def prepare_to_run(self, clock, period_count): """ Prepare the entity for execution. :param clock: The clock containing the execution start time and execution period information. :param period_count: The total amount of periods this activity will be requested to be run for. """ self.period_count = period_count self._exec_year_end_datetime = clock.get_datetime_at_period_ix( period_count) self._prev_year_end_datetime = clock.start_datetime self._curr_year_end_datetime = clock.start_datetime + relativedelta( years=1) # Remove all the transactions del self.gl.transactions[:] for c in self.components: c.prepare_to_run(clock, period_count) self.negative_income_tax_total = 0 def run(self, clock): """ Execute the entity at the current clock cycle. :param clock: The clock containing the current execution time and period information. """ if clock.timestep_ix >= self.period_count: return for c in self.components: c.run(clock, self.gl) self._perform_year_end_procedure(clock) def _perform_year_end_procedure(self, clock): if clock.get_datetime() >= self._curr_year_end_datetime\ or clock.timestep_ix == self.period_count: gls = self.gl.structure year_start_date = self._prev_year_end_datetime year_end_date = self._curr_year_end_datetime + \ timedelta(seconds=-1) self._prev_year_end_datetime = self._curr_year_end_datetime self._curr_year_end_datetime += relativedelta(years=1) if self._curr_year_end_datetime > self._exec_year_end_datetime: self._curr_year_end_datetime = self._exec_year_end_datetime gross_profit_write_off_accs = OrderedDict() inc_summary_write_off_accs = OrderedDict() sales_accs = gls.get_account_descendants(gls._acci_sales_) cost_of_sales_accs = gls.get_account_descendants(gls._acci_cos_) year_taxes = [] for tx in self.gl.transactions: if year_start_date <= tx.tx_date <= year_end_date: year_taxes.append(tx) for tx in year_taxes: cr_acc = gls.get_account(tx.cr_account) dt_acc = gls.get_account(tx.dt_account) if cr_acc in 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 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: 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.expense: if dt_acc in inc_summary_write_off_accs: inc_summary_write_off_accs[dt_acc] += tx.amount else: inc_summary_write_off_accs[dt_acc] = tx.amount inc_sum = self._perform_year_end_gross_profit_and_income_summary( year_end_date, gross_profit_write_off_accs, inc_summary_write_off_accs) inc_sum = self._perform_year_end_income_tax(year_end_date, inc_sum) self._perform_year_end_retained_earnings(year_end_date, inc_sum) def _perform_year_end_gross_profit_and_income_summary( self, year_end_datetime, gross_profit_write_off_accounts, income_summary_write_off_accounts): gls = self.gl.structure gross_profit = self._perform_year_end_gross_profit( year_end_datetime, gross_profit_write_off_accounts) income_summary_amount = self._perform_year_end_income_summary( year_end_datetime, gross_profit, income_summary_write_off_accounts) def create_tx(dt_account, cr_account): tx_name = "Settle the '" + gls._acci_gross_prof_.path +\ "' Account" new_tx = self.gl.create_transaction(tx_name, description=tx_name, tx_date=year_end_datetime, dt_account=dt_account, cr_account=cr_account, source=self.path, amount=abs(gross_profit)) new_tx.is_closing_cr_account = True if gross_profit > 0: create_tx(gls._acci_gross_prof_.path, gls._acci_inc_sum_.path) elif gross_profit < 0: create_tx(gls._acci_inc_sum_.path, gls._acci_gross_prof_.path) return income_summary_amount def _perform_year_end_gross_profit(self, year_end_datetime, gross_profit_write_off_accounts): gls = self.gl.structure gross_profit = 0 for acc, amount in gross_profit_write_off_accounts.items(): def create_tx(dt_account, cr_account): tx_name = "Settle the '" + acc.path + "' Account" new_tx = self.gl.create_transaction(tx_name, description=tx_name, tx_date=year_end_datetime, dt_account=dt_account, cr_account=cr_account, source=self.path, amount=abs(amount)) new_tx.is_closing_cr_account = True gross_profit += amount if amount > 0: create_tx(gls._acci_gross_prof_.path, acc.path) elif amount < 0: create_tx(acc.path, gls._acci_gross_prof_.path) return gross_profit def _perform_year_end_income_summary(self, year_end_datetime, gross_profit, income_summary_write_off_accounts): gls = self.gl.structure income_summary_amount = gross_profit for acc, amount in income_summary_write_off_accounts.items(): def create_tx(dt_account, cr_account): tx_name = "Settle the '" + acc.path + "' Account" new_tx = self.gl.create_transaction(tx_name, description=tx_name, tx_date=year_end_datetime, dt_account=dt_account, cr_account=cr_account, source=self.path, amount=abs(amount)) new_tx.is_closing_cr_account = True if amount > 0: if acc.account_type == AccountType.expense: income_summary_amount -= amount create_tx(gls._acci_inc_sum_.path, acc.path) else: income_summary_amount += amount create_tx(acc.path, gls._acci_inc_sum_.path) elif amount < 0: if acc.account_type == AccountType.expense: income_summary_amount -= amount create_tx(acc.path, gls._acci_inc_sum_.path) else: income_summary_amount += amount create_tx(gls._acci_inc_sum_.path, acc.path) return income_summary_amount def _perform_year_end_income_tax(self, year_end_datetime, income_summary_amount): return income_summary_amount def _perform_year_end_retained_earnings(self, year_end_datetime, income_summary_amount): def create_tx(dt_account, cr_account): tx_name = "Settle the '" + gls._acci_inc_sum_.path +\ "' Account, adjust Retained Earnings accordingly." new_tx = self.gl.create_transaction(tx_name, description=tx_name, tx_date=year_end_datetime, dt_account=dt_account, cr_account=cr_account, source=self.path, amount=income_summary_amount) new_tx.is_closing_cr_account = True gls = self.gl.structure if income_summary_amount > 0: create_tx(gls._acci_inc_sum_.path, gls._accb_ret_earnings_acc_.path) elif income_summary_amount < 0: create_tx(gls._accb_ret_earnings_acc_.path, gls._acci_inc_sum_.path)