Ejemplo n.º 1
0
    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)