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_journalentry_passes(self):

        test_dump = 'value\tdate\ttype\t[03-0450]\t[03-0709]\t[15-1905]\t[15-1903]\t[15-1910]\t[15-1901]\t[15-1900]\t[03-0600]\t[15-1950]\r\n23,017.03\tJan. 31, 2016\tJournalEntry\t-17,817.96\t-3,447.00\t2,385.02\t6,991.98\t730.77\t8,255.34\t2,901.85\t-1,752.07\t1,752.07'  # noqa

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

        test_transaction = Transaction.objects.get(
            value=utils.make_decimal('23017.03'),
            date=dateparser.parse('31-Jan-2016'),
            source='subledgers.journals.models.JournalEntry',
            user=self.user)
        test_lines = [
            Line.objects.get(transaction=test_transaction,
                             account=self.ac,
                             value=utils.make_decimal(-17817.96)),
            Line.objects.get(transaction=test_transaction,
                             account=self.ap,
                             value=utils.make_decimal(-3447)),
            Line.objects.get(transaction=test_transaction,
                             account=self.ab,
                             value=utils.make_decimal(2385.02)),
            Line.objects.get(transaction=test_transaction,
                             account=self.af,
                             value=utils.make_decimal(6991.98)),
            Line.objects.get(transaction=test_transaction,
                             account=self.ag,
                             value=utils.make_decimal(730.77)),
            Line.objects.get(transaction=test_transaction,
                             account=self.ak,
                             value=utils.make_decimal(8255.34)),
            Line.objects.get(transaction=test_transaction,
                             account=self.ast,
                             value=utils.make_decimal(2901.85)),
            Line.objects.get(transaction=test_transaction,
                             account=self.asl,
                             value=utils.make_decimal(-1752.07)),
            Line.objects.get(transaction=test_transaction,
                             account=self.asu,
                             value=utils.make_decimal(1752.07)),
        ]
        test_result = [
            JournalEntry.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_failure_transaction_object_delete(self):  # noqa

        # has blank entity, should fail to create CreditorInvoice
        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\n\t02-Jun-2017\tI38731476\tO37696095\t$485.27\t$0.65\tguild house\t6.5\t478.12\t\t\t"  # NOQA

        self.assertRaises(Exception,
                          convert_import_to_objects,
                          test_dump,
                          user=self.user,
                          object_name='CreditorInvoice')

        test_transaction_kwargs = {
            'value': utils.make_decimal('$485.27'),
            'date': dateparser.parse('02-Jun-2017'),
            'source': 'subledgers.creditors.models.CreditorInvoice',
            'user': self.user
        }

        self.assertRaises(ObjectDoesNotExist, Transaction.objects.get,
                          **test_transaction_kwargs)

        # This test saved me one time, when Entry was finding a way to be
        # created anyway, because wasn't validating `value` = bal.

        test_transaction_kwargs = {
            'source': 'subledgers.creditors.models.CreditorInvoice',
            'user': self.user
        }

        self.assertEqual(
            Transaction.objects.filter(**test_transaction_kwargs).count(), 0)
    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_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_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))
예제 #7
0
    def process_kwargs(self, kwargs):
        """
        Minimum keys assumed included: 'user', 'date', 'lines'

        1. Keys added (if not already defined): 'cls', 'source'
             add `source` using ledgers.utils.get_source(`Model`)
             based upon `Model` provided in object settings

        2. Keys checked: 'relation', dates, decimals, required fields
             IS_DATE using dateparser.parse
             IS_DECIMAL using ledgers.utils.make_decimal()
             IS_RELATION to normalise relation field name

        3. Create dicts: (obj_kwargs, trans_kwargs)

        Check all required fields are represented (or explode)
             append `row_dict` set to `list_kwargs`
        """

        # Generate list of codes to check against.
        # Cheaper than checking db for every account.
        ACCOUNT_CODE_LIST = Account.get_account_code_list()

        process_kwargs = {k.lower(): v for k, v in kwargs.items()}

        # If `cls` not manually described in kwargs.
        process_kwargs['source'] = utils.get_source(self)

        for key in kwargs:
            if key in settings.FIELD_IS_DATE:
                process_kwargs[key] = utils.make_date(kwargs[key])

            if key in settings.FIELD_IS_DECIMAL:
                process_kwargs[key] = utils.make_decimal(kwargs[key])

            if key in settings.FIELD_IS_RELATION:
                # Relation names are not always consistently used.
                # eg. Creditor, Relation
                if kwargs[key] is None:
                    # Is likely to have emtpy relation column heading.
                    # Remove empty relation, so doesn't blow up save.
                    process_kwargs.pop(key)
                else:
                    process_kwargs['relation'] = self.get_relation(kwargs[key])

            if key in ACCOUNT_CODE_LIST:
                process_kwargs.setdefault('accounts', []).append(
                    (key, kwargs[key]))

        self.check_required(process_kwargs)

        return process_kwargs
    def test_create_object_single_expense_using_entity_GST_variation_passes(
            self):  # noqa

        # GST allocated, not using `gst_total` field.
        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\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')

        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,
                relation=self.entity0,
            )
        ]

        self.assertEqual(test_create_object, test_result)
        self.assertEqual(set(list(test_result[0].transaction.lines.all())),
                         set(test_lines))
예제 #9
0
 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)))]
예제 #10
0
 def process_account(self, account, val):
     """ If only account is provided, retrieve tb account. """
     return [(Account.get_account(account),
              utils.set_DR(utils.make_decimal(val)))]
예제 #11
0
 def test_make_decimal_neg_str_passes(self):
     test_input = '-5'
     test_result = Decimal('-5.00')
     self.assertEqual(utils.make_decimal(test_input), test_result)
예제 #12
0
 def test_make_decimal_Decimal_passes(self):
     test_input = Decimal(5)
     test_result = Decimal('5.00')
     self.assertEqual(utils.make_decimal(test_input), test_result)
예제 #13
0
def process_tax(cls, kwargs, lines):
    """ Just a check that GST is defined if required.

    If subledger requires GST error will be raised if GST
    not defined.

    GST should be defined in one of two ways:
    - GST tb account being used
    - `GST total` column/ `gst_total` key in kwargs
    """

    if not settings.OBJECT_SETTINGS.get(utils.get_source_name(cls)):
        # Tax not applicable to this subledgers
        return lines

    object_settings = settings.OBJECT_SETTINGS[utils.get_source_name(cls)]

    # @@ TODO facilitate other taxes and surcharges.
    if object_settings.get('is_GST'):

        # There are 2 methods of adding GST:
        # 1. defining GST_CR_ACCOUNT or GST_DR_ACCOUNT among lines
        #  or
        # 2. defining `GST_total` column on import

        # First check if GST_CR_ACCOUNT or GST_DR_ACCOUNT lines exist
        gst_allocated = False
        for line in lines:
            if Account.get_account(line[0]) == \
               Account.get_account(settings.GST_DR_ACCOUNT)\
               or Account.get_account(line[0]) == \
               Account.get_account(settings.GST_CR_ACCOUNT):
                gst_allocated = True

        # If not:
        # - set line value using `GST_total` column value
        # - set acccount using `is_tb_account_DR/CR` to get `GST_DR/CR_ACCOUNT`
        # Note: the value +/- is correct to subledger. May not be correct for
        #       the tb. +/- corrected to tb set in different process.

        if not gst_allocated:
            # note: correct GST account, abs value
            # fix dr/cr +/- in next process, not here.

            if not kwargs['gst_total'] in ['', None, 0]:
                if object_settings.get('is_tb_account_DR'):
                    lines.append((settings.GST_DR_ACCOUNT,
                                  utils.make_decimal(kwargs['gst_total'])))
                if object_settings.get('is_tb_account_CR'):
                    lines.append((settings.GST_CR_ACCOUNT,
                                  utils.make_decimal(kwargs['gst_total'])))

            if kwargs.get('gst_total'):
                gst_allocated = True

        else:
            pass

            # @@ TODO Can add GSTEntity or GSTAccount here.
            # raise Exception('GST not represted.')

    return lines