Skip to content

Commit

Permalink
Skip Export: Category Support as Condition Field for Sage300 (#158)
Browse files Browse the repository at this point in the history
* Category Support as Condition Field

* Fix for category support

* updated code for category and boolean

* add tests

* fixed tests
  • Loading branch information
anishfyle authored May 15, 2024
1 parent 27c4059 commit 4eb2dca
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 2 deletions.
5 changes: 5 additions & 0 deletions apps/fyle/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,10 @@
'field_name': 'spent_at',
'type': 'DATE',
'is_custom': False
},
{
'field_name': 'category',
'type': 'SELECT',
'is_custom': False
}
]
9 changes: 8 additions & 1 deletion apps/fyle/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,14 @@ def construct_expense_filter(expense_filter):
else:
# If the isnull filter value is False, invert the exact filter using the ~Q operator and assign it to the constructed expense filter
constructed_expense_filter = ~Q(**filter2)

# for category non-custom field with not_in as operator, to check this later on
elif expense_filter.condition == 'category' and expense_filter.operator == 'not_in' and not expense_filter.is_custom:
# construct the filter
filter1 = {
f'{expense_filter.condition}__in': expense_filter.values
}
# Invert the filter using the ~Q operator and assign it to the constructed expense filter
constructed_expense_filter = ~Q(**filter1)
# For all non-custom fields
else:
# Construct the filter for the non-custom field
Expand Down
19 changes: 19 additions & 0 deletions apps/fyle/migrations/0003_alter_expensefilter_custom_field_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.1.2 on 2024-05-14 14:18

from django.db import migrations
import sage_desktop_api.models.fields


class Migration(migrations.Migration):

dependencies = [
('fyle', '0002_expense_is_skipped'),
]

operations = [
migrations.AlterField(
model_name='expensefilter',
name='custom_field_type',
field=sage_desktop_api.models.fields.StringOptionsField(choices=[('SELECT', 'SELECT'), ('NUMBER', 'NUMBER'), ('TEXT', 'TEXT'), ('BOOLEAN', 'BOOLEAN')], default='', help_text='Custom field type', max_length=255, null=True),
),
]
3 changes: 2 additions & 1 deletion apps/fyle/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
EXPENSE_FILTER_CUSTOM_FIELD_TYPE = (
('SELECT', 'SELECT'),
('NUMBER', 'NUMBER'),
('TEXT', 'TEXT')
('TEXT', 'TEXT'),
('BOOLEAN', 'BOOLEAN')
)

EXPENSE_FILTER_OPERATOR = (
Expand Down
199 changes: 199 additions & 0 deletions tests/test_fyle/test_helpers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import pytest
from requests import Response
from apps.fyle.helpers import (
Q,
construct_expense_filter,
get_fyle_orgs,
get_request,
post_request,
Expand Down Expand Up @@ -139,3 +142,199 @@ def test_construct_expense_filter_query(
returned_filter = construct_expense_filter_query(expense_filters=expense_payload_req)

assert str(returned_filter) == "(OR: ('custom_properties__some_field__isnull', True), ('custom_properties__some_field__exact', None), ('custom_properties__employee_id__not_in', [12, 13]), ('custom_properties__is_email_sent__not_in', False))"


@pytest.mark.django_db()
def test_construct_expense_filter():
# employee-email-is-equal
expense_filter = ExpenseFilter(condition='employee_email', operator='in', values=['[email protected]', '[email protected]'], rank=1)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'employee_email__in': ['[email protected]', '[email protected]']}
response = Q(**filter_1)

assert constructed_expense_filter == response

# employee-email-is-equal-one-email-only
expense_filter = ExpenseFilter(condition='employee_email', operator='in', values=['[email protected]'], rank=1)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'employee_email__in': ['[email protected]']}
response = Q(**filter_1)

assert constructed_expense_filter == response

# claim-number-is-equal
expense_filter = ExpenseFilter(condition='claim_number', operator='in', values=['ajdnwjnadw', 'ajdnwjnlol'], rank=1)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'claim_number__in': ['ajdnwjnadw', 'ajdnwjnlol']}
response = Q(**filter_1)

assert constructed_expense_filter == response

# claim-number-is-equal-one-claim_number-only
expense_filter = ExpenseFilter(condition='claim_number', operator='in', values=['ajdnwjnadw'], rank=1)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'claim_number__in': ['ajdnwjnadw']}
response = Q(**filter_1)

assert constructed_expense_filter == response

# report-name-is-equal
expense_filter = ExpenseFilter(condition='report_title', operator='iexact', values=['#17: Dec 2022'], rank=1)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'report_title__iexact': '#17: Dec 2022'}
response = Q(**filter_1)

assert constructed_expense_filter == response

# report-name-contains
expense_filter = ExpenseFilter(condition='report_title', operator='icontains', values=['Dec 2022'], rank=1)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'report_title__icontains': 'Dec 2022'}
response = Q(**filter_1)

assert constructed_expense_filter == response

# spent-at-is-before
expense_filter = ExpenseFilter(condition='spent_at', operator='lt', values=['2020-04-20 23:59:59+00'], rank=1)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'spent_at__lt': '2020-04-20 23:59:59+00'}
response = Q(**filter_1)

assert constructed_expense_filter == response

# spent-at-is-on-or-before
expense_filter = ExpenseFilter(condition='spent_at', operator='lte', values=['2020-04-20 23:59:59+00'], rank=1)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'spent_at__lte': '2020-04-20 23:59:59+00'}
response = Q(**filter_1)

assert constructed_expense_filter == response

# category_in
expense_filter = ExpenseFilter(
condition = 'category',
operator = 'in',
values = ['anish'],
rank = 1
)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'category__in':['anish']}
response = Q(**filter_1)

assert constructed_expense_filter == response

# category_not_in
expense_filter = ExpenseFilter(
condition = 'category',
operator = 'not_in',
values = ['anish', 'singh'],
rank = 1
)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'category__in':['anish', 'singh']}
response = ~Q(**filter_1)

assert constructed_expense_filter == response

# custom-properties-number-is-equal
expense_filter = ExpenseFilter(condition='Gon Number', operator='in', values=[102, 108], rank=1, is_custom=True)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'custom_properties__Gon Number__in': [102, 108]}
response = Q(**filter_1)

assert constructed_expense_filter == response

# custom-properties-number-is-not-empty
expense_filter = ExpenseFilter(condition='Gon Number', operator='isnull', values=['False'], rank=1, is_custom=True)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'custom_properties__Gon Number__exact': None}
response = ~Q(**filter_1)

assert constructed_expense_filter == response

# custom-properties-number-is--empty
expense_filter = ExpenseFilter(condition='Gon Number', operator='isnull', values=['True'], rank=1, is_custom=True)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'custom_properties__Gon Number__isnull': True}
filter_2 = {'custom_properties__Gon Number__exact': None}
response = Q(**filter_1) | Q(**filter_2)

assert constructed_expense_filter == response

# custom-properties-text-is-equal
expense_filter = ExpenseFilter(condition='Killua Text', operator='in', values=['hunter', 'naruto', 'sasuske'], rank=1, is_custom=True)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'custom_properties__Killua Text__in': ['hunter', 'naruto', 'sasuske']}
response = Q(**filter_1)

assert constructed_expense_filter == response

# custom-properties-text-is-not-empty
expense_filter = ExpenseFilter(condition='Killua Text', operator='isnull', values=['False'], rank=1, is_custom=True)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'custom_properties__Killua Text__exact': None}
response = ~Q(**filter_1)

assert constructed_expense_filter == response

# custom-properties-text-is--empty
expense_filter = ExpenseFilter(condition='Killua Text', operator='isnull', values=['True'], rank=1, is_custom=True)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'custom_properties__Killua Text__isnull': True}
filter_2 = {'custom_properties__Killua Text__exact': None}
response = Q(**filter_1) | Q(**filter_2)

assert constructed_expense_filter == response

# custom-properties-select-is-equal
expense_filter = ExpenseFilter(condition='Kratos', operator='in', values=['BOOK', 'Dev-D'], rank=1, is_custom=True)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'custom_properties__Kratos__in': ['BOOK', 'Dev-D']}
response = Q(**filter_1)

assert constructed_expense_filter == response

# custom-properties-select-is-equal-one-value
expense_filter = ExpenseFilter(condition='Kratos', operator='in', values=['BOOK'], rank=1, is_custom=True)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'custom_properties__Kratos__in': ['BOOK']}
response = Q(**filter_1)

assert constructed_expense_filter == response

# custom-properties-select-is-not-empty
expense_filter = ExpenseFilter(condition='Kratos', operator='isnull', values=['False'], rank=1, is_custom=True)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'custom_properties__Kratos__exact': None}
response = ~Q(**filter_1)

assert constructed_expense_filter == response

# custom-properties-select-is--empty
expense_filter = ExpenseFilter(condition='Kratos', operator='isnull', values=['True'], rank=1, is_custom=True)
constructed_expense_filter = construct_expense_filter(expense_filter)

filter_1 = {'custom_properties__Kratos__isnull': True}
filter_2 = {'custom_properties__Kratos__exact': None}
response = Q(**filter_1) | Q(**filter_2)

assert constructed_expense_filter == response

0 comments on commit 4eb2dca

Please sign in to comment.