def test_create_object_single_sale_passes(self):

        test_dump = 'value\tdate\ttype\tgst_total\t[10-0100]\r\n3054.6\tJan. 23, 2016\tSale\t277.69\t2776.91'  # noqa

        test_create_object = convert_import_to_objects(test_dump,
                                                       user=self.user,
                                                       object_name='Sale')

        test_transaction = Transaction.objects.get(
            value=utils.make_decimal('3054.6'),
            date=dateparser.parse('23-Jan-2016'),
            source='subledgers.sales.models.Sale',
            user=self.user)

        test_lines = [
            Line.objects.get(transaction=test_transaction,
                             account=self.SALES_CLEARING_ACCOUNT,
                             value=utils.set_DR('3054.6')),
            Line.objects.get(transaction=test_transaction,
                             account=self.a1,
                             value=utils.set_CR('2776.91')),
            Line.objects.get(transaction=test_transaction,
                             account=self.account_DR_GST,
                             value=utils.set_CR('277.69')),
        ]
        test_result = [Sale.objects.get(transaction=test_transaction, )]

        self.assertEqual(test_create_object, test_result)
        self.assertEqual(set(list(test_result[0].transaction.lines.all())),
                         set(test_lines))
    def test_create_object_single_expense_no_entity_passes(self):

        test_dump = 'value\tdate\tnote\ttype\trelation\tgst_total\t[15-1420]\t[15-0715]\t[15-0605]\t[15-0150]\t[15-0500]\t[15-0650]\t[15-0705]\t[15-0710]\t[15-1010]\t[15-1400]\t[15-1430]\t[15-0620]\t[15-1470]\r\n53.47\t11-Dec-2015\t7-ELEVEN 2296 ERINDALE CENT\tExpense\t\t4.86\t\t\t\t48.61\t\t\t\t\t\t\t\t\t'  # noqa

        test_create_object = convert_import_to_objects(test_dump,
                                                       user=self.user,
                                                       object_name='Expense')

        # `.get(..` MUST BE BELOW `test_create_object`
        # get the objects that look exactly correct
        test_transaction = Transaction.objects.get(
            value=utils.make_decimal('53.47'),
            date=dateparser.parse('11-Dec-2015'),
            source='subledgers.expenses.models.Expense',
            note='7-ELEVEN 2296 ERINDALE CENT',
            user=self.user)
        test_lines = [
            Line.objects.get(transaction=test_transaction,
                             account=self.a1,
                             value=utils.set_DR('48.61')),
            Line.objects.get(transaction=test_transaction,
                             account=self.EXPENSE_CLEARING_ACCOUNT,
                             value=utils.set_CR('53.47')),
            Line.objects.get(transaction=test_transaction,
                             account=self.account_CR_GST,
                             value=utils.set_DR('4.86')),
        ]
        test_result = [Expense.objects.get(transaction=test_transaction, )]

        self.assertEqual(test_create_object, test_result)
        self.assertEqual(set(list(test_result[0].transaction.lines.all())),
                         set(test_lines))
    def test_create_object_single_incomplete_kwarg_failure(self):

        test_kwargs = {
            'relation':
            self.creditor0,
            # 'object': 'CreditorInvoice', # no object failure
            'date':
            dateparser.parse('02-Jun-2017'),
            'gst_total':
            utils.make_decimal('$0.65'),
            'invoice_number':
            'I38731476',
            'order_number':
            'guild house',
            'reference':
            'O37696095',
            'source':
            'subledgers.creditors.models.CreditorInvoice',
            'value':
            utils.make_decimal('$485.27'),
            'user':
            self.user,
            'lines': [
                (self.a1, utils.set_DR('478.12')),
                (self.a2, utils.set_DR('6.5')),
                (self.account_creditors, utils.set_CR('485.27')),  # noqa
                (self.account_GST, utils.set_DR('0.65')),
            ]
        }
        self.assertRaises(Exception, convert_import_to_objects, test_kwargs)
    def test_create_object_single_expense_in_credit_passes(self):  # noqa

        # Is a credit (ie negative value expense)
        test_dump = 'value\tdate\tnote\ttype\trelation\t[03-0733]\t[15-1420]\t[15-0715]\t[15-0605]\t[15-0150]\t[15-0500]\t[15-0650]\t[15-0705]\t[15-0710]\t[15-1010]\t[15-1400]\t[15-1430]\t[15-0620]\t[15-1470]\r\n53.47\t11-Dec-2015\t7-ELEVEN 2296 ERINDALE CENT\tExpense\t7ELEVE\t-4.86\t\t\t\t-48.61\t\t\t\t\t\t\t\t\t'  # noqa

        test_create_object = convert_import_to_objects(test_dump,
                                                       user=self.user,
                                                       object_name='Expense')

        test_transaction = Transaction.objects.get(
            value=utils.make_decimal('53.47'),
            date=dateparser.parse('11-Dec-2015'),
            source='subledgers.expenses.models.Expense',
            note='7-ELEVEN 2296 ERINDALE CENT',
            user=self.user)
        test_lines = [
            Line.objects.get(transaction=test_transaction,
                             account=self.a1,
                             value=utils.set_CR('48.61')),
            Line.objects.get(transaction=test_transaction,
                             account=self.EXPENSE_CLEARING_ACCOUNT,
                             value=utils.set_DR('53.47')),
            Line.objects.get(transaction=test_transaction,
                             account=self.account_CR_GST,
                             value=utils.set_CR('4.86')),
        ]
        test_result = [
            Expense.objects.get(
                transaction=test_transaction,
                relation=self.entity0,
            )
        ]

        self.assertEqual(test_create_object, test_result)
        self.assertEqual(set(list(test_result[0].transaction.lines.all())),
                         set(test_lines))
    def test_create_object_single_creditor_invoice_using_creditor_invoice(
            self):  # noqa

        test_dump = "creditor\tdate\tinvoice_number\treference\tvalue\tgst_total\torder_number\t[15-0608]\t[15-0151]\t[15-0155]\t[15-0301]\t[15-0305]\r\nBIDVES\t02-Jun-2017\tI38731476\tO37696095\t485.27\t0.65\tguild house\t6.5\t478.12\t\t\t"  # NOQA
        test_create_object = convert_import_to_objects(
            test_dump, user=self.user, object_name='CreditorInvoice')

        # `.get(..` MUST BE BELOW `test_create_object`
        # get the objects that look exactly correct
        test_transaction = Transaction.objects.get(
            value=utils.make_decimal('485.27'),
            date=dateparser.parse('02-Jun-2017'),
            source='subledgers.creditors.models.CreditorInvoice',
            user=self.user)
        test_lines = [
            Line.objects.get(transaction=test_transaction,
                             account=self.a1,
                             value=utils.set_DR('478.12')),
            Line.objects.get(transaction=test_transaction,
                             account=self.a2,
                             value=utils.set_DR('6.5')),
            Line.objects.get(transaction=test_transaction,
                             account=self.account_creditors,
                             value=utils.set_CR('485.27')),
            Line.objects.get(transaction=test_transaction,
                             account=self.account_CR_GST,
                             value=utils.set_DR('0.65')),
        ]
        test_result = [
            CreditorInvoice.objects.get(
                transaction=test_transaction,
                relation=self.creditor0,
                gst_total=utils.make_decimal('0.65'),
                invoice_number='I38731476',
                order_number='guild house',
                reference='O37696095',
            )
        ]

        self.assertEqual(test_create_object, test_result)
        self.assertEqual(set(list(test_result[0].transaction.lines.all())),
                         set(test_lines))
 def process_line(self, account_DR, account_CR, val):
     return [(Account.get_account(account_DR),
              utils.set_DR(utils.make_decimal(val))),
             (Account.get_account(account_CR),
              utils.set_CR(utils.make_decimal(val)))]
    def make_lines(self, kwargs):
        """
        Create and add `lines` list of tuples:
        1. normalise `account`, `accounts` and `account_CR`/`account_DR`
           to `lines`.

        2. add `gst_total` [optional, if specified in object settings]


        3. correct CR/DR using .set_lines_sign()
           (this is a big deal)

        4. add `lines` back to `kwargs`
        """
        lines = ()
        if kwargs.get('lines'):

            # Lines are completely manual.
            # Should never be used by 'standard' subledgers:
            # Debtor/Creditor, Sales/Expense

            # Prioritise `lines` if defined in kwargs
            self.check_lines_equals_value(kwargs)
            lines = kwargs['lines']
        elif kwargs.get('account_dr') \
                and kwargs.get('account_cr') \
                and kwargs.get('value'):
            # Next try `account_DR`, `account_CR`, `value` combination
            # should be lowercase
            lines = self.process_line(kwargs.get('account_dr'),
                                      kwargs.get('account_cr'),
                                      kwargs.get('value'))
            # Next check for `inlines_accounts`
        elif kwargs.get('accounts') or kwargs.get('account'):

            # Accounts should *always* be used by 'standard' subledgers:
            # Debtor/Creditor, Sales/Expense
            # @@ TODO formalise 'standard' subledgers use of `accounts`
            # rather than `lines`

            # Next try normalising `account`/`accounts`
            if kwargs.get('accounts'):
                accounts = self.process_accounts(kwargs.get('accounts'))
            elif kwargs.get('account'):
                accounts = self.process_account(kwargs.get('account'),
                                                kwargs.get('value'))

            # Check tax on 'standard' subledgers only.
            # Should be done before tb account is added.

            # In this early case, all thise means is checking that if GST
            # is required, that it has been added.

            # @@ TODO: Doesn't check IF tax should be included.
            # Should explode as necessary.
            accounts = self.process_lines_tax(kwargs, accounts)

            # Convert `accounts` to `lines` (ie `accounts` + tb account)
            if self.get_tb_account():
                accounts.append(
                    (self.get_tb_account(),
                     utils.set_CR(self.get_lines_balance(accounts))))

            lines = accounts
        else:
            # fails here if a condition for providing lines is not met.
            raise Exception(
                "Lines/Accounts were not found in input: {}.".format(kwargs))

        # Should now have a set of normalised lines.

        # @@ TOOD: check tb account not added incorrectly
        # @@ TOOD: protected reserved tb accounts?
        # @@ TODO: allow multiple methods to be used?

        # Trial Balance DR/CR Correction
        # This is confusing. Needs to be thoroughly checked.
        # At this point `lines` are correct for subledger.
        # Eg. - Increase in sales is positive.
        #     - Additional expense is positive.
        # Now fix `lines` to ensure correct +/- (dr/cr) for tb.
        lines = self.set_lines_sign(lines)

        # check lines are OK.
        if self.get_lines_balance(lines):
            raise Exception(
                "Lines do not balance to zero. Input: {}.".format(kwargs))

        return lines