def close_accounts(self, request): accounts = Account.objects.filter(is_active=True, account_type__category__in=[2, 3, 4]) income_value = 0 debits = [] credits = [] has_income_adjustment = False closing_journal = JournalEntry( date=timezone.now(), creator=request.user, description="Auto-generated closing journal", entry_type=JournalEntryTypes.CLOSING, is_approved=None) closing_journal.save() for account in accounts: balance = account.get_balance() if balance == 0: # No need to close an account that does not have a balance continue closer = Transaction(affected_account=account, journal_entry=closing_journal, is_debit=not account.is_debit(), value=abs(balance)) if account.account_type.category == 3 or account.account_type.category == 4: has_income_adjustment = True if closer.is_debit: debits.append(closer) else: credits.append(closer) income_value += closer.get_value() elif account.account_type.category == 2 and "Drawing" in account.name: # NOTE: We are only accounting for business owner equity here, not shareholders equity. try: equity_adjuster = Account.objects.get_by_natural_key( account.name.replace("Drawing", "Capital")) if not equity_adjuster.is_active: equity_adjuster.is_active = True equity_adjuster.save() except Model.DoesNotExist: closing_journal.delete() return Response({ 'message': 'The Drawing account "%s" does not have a corresponding Capital account to adjust.' % \ account.name }, status=403) debits.append( Transaction(affected_account=equity_adjuster, journal_entry=closing_journal, value=abs(balance), is_debit=True)) credits.append(closer) if not len(debits) and not len(credits): closing_journal.delete() return Response({'message': 'Accounts have already been closed.'}, status=200) if has_income_adjustment: try: income_account = Account.objects.get_by_natural_key( 'Retained Earnings') if not income_account.is_active: income_account.is_active = True income_account.save() except Model.DoesNotExist: closing_journal.delete() return Response( { 'message': 'There is no acccount named "Retaining Earnings".' }, status=403) income_adjuster = Transaction(affected_account=income_account, journal_entry=closing_journal, value=abs(income_value)) income_adjuster.is_debit = income_value < 0 # if income_value is positive, it debits the Retained Earnings else credits if income_adjuster.is_debit: debits.append(income_adjuster) else: credits.append(income_adjuster) transaction_list = debits + credits for transaction in transaction_list: transaction.save() return Response({'message': 'Closing Entry has been created.'}, status=200)