Skip to content

Commit

Permalink
Settings category mapping error and resolving (#446)
Browse files Browse the repository at this point in the history
* category mapping error settings and resolution

* test added

* Setting tax mapping and resolve (#447)

* Setting tax mapping and resolve

* resolved comments

* Setting and Resolving Netsuite Error (#448)

* Setting Netsuite Error

* resolving netsuite error

* setting netsuite error resolved

* comment resolved

---------

Co-authored-by: Ashutosh619-sudo <[email protected]>

---------

Co-authored-by: Ashutosh619-sudo <[email protected]>

---------

Co-authored-by: Ashutosh619-sudo <[email protected]>
  • Loading branch information
Ashutosh619-sudo and Ashutosh619-sudo authored Nov 27, 2023
1 parent dc81ada commit 24fabfa
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 3 deletions.
20 changes: 19 additions & 1 deletion apps/mappings/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.dispatch import receiver
from django_q.tasks import async_task

from fyle_accounting_mappings.models import MappingSetting, EmployeeMapping, Mapping
from fyle_accounting_mappings.models import MappingSetting, EmployeeMapping, Mapping, CategoryMapping

from apps.mappings.tasks import upload_attributes_to_fyle, schedule_cost_centers_creation,\
schedule_fyle_attributes_creation
Expand All @@ -18,6 +18,24 @@
from .models import GeneralMapping, SubsidiaryMapping
from .tasks import schedule_auto_map_ccc_employees

@receiver(post_save, sender=Mapping)
def resolve_post_mapping_errors(sender, instance: Mapping, **kwargs):
"""
Resolve errors after mapping is created
"""
if instance.source_type == 'TAX_GROUP':
Error.objects.filter(expense_attribute_id=instance.source_id).update(
is_resolved=True
)

@receiver(post_save, sender=CategoryMapping)
def resolve_post_category_mapping_errors(sender, instance: Mapping, **kwargs):
"""
Resolve errors after mapping is created
"""
Error.objects.filter(expense_attribute_id=instance.source_category_id).update(
is_resolved=True
)

@receiver(post_save, sender=EmployeeMapping)
def resolve_post_employees_mapping_errors(sender, instance: Mapping, **kwargs):
Expand Down
9 changes: 9 additions & 0 deletions apps/mappings/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,9 @@ def post_tax_groups(platform_connection: PlatformConnector, workspace_id: int):

platform_connection.tax_groups.sync()
Mapping.bulk_create_mappings(netsuite_attributes, 'TAX_GROUP', 'TAX_ITEM', workspace_id)
resolve_expense_attribute_errors(
source_attribute_type='TAX_GROUP', workspace_id=workspace_id
)

@handle_exceptions(task_name='Import Category to Fyle and Auto Create Mappings')
def auto_create_category_mappings(workspace_id):
Expand Down Expand Up @@ -563,6 +566,12 @@ def auto_create_category_mappings(workspace_id):
if reimbursable_expenses_object == 'EXPENSE REPORT' and \
corporate_credit_card_expenses_object in ('BILL', 'JOURNAL ENTRY', 'CREDIT CARD CHARGE'):
bulk_create_ccc_category_mappings(workspace_id)

resolve_expense_attribute_errors(
source_attribute_type="CATEGORY",
destination_attribute_type=reimbursable_destination_type,
workspace_id=workspace_id
)


def auto_import_and_map_fyle_fields(workspace_id):
Expand Down
34 changes: 33 additions & 1 deletion apps/netsuite/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import traceback

from apps.fyle.models import ExpenseGroup
from apps.tasks.models import TaskLog
from apps.tasks.models import TaskLog, Error
from apps.workspaces.models import LastExportDetail, NetSuiteCredentials

from netsuitesdk.internal.exceptions import NetSuiteRequestError
Expand All @@ -27,6 +27,17 @@ def __handle_netsuite_connection_error(expense_group: ExpenseGroup, task_log: Ta
'expense_group_id': expense_group.id,
'message': 'NetSuite Account not connected'
}

Error.objects.update_or_create(
workspace_id=expense_group.workspace_id,
expense_group=expense_group,
defaults={
'type': 'NETSUITE_ERROR',
'error_title': netsuite_error_message,
'error_detail': detail['message'],
'is_resolved': False
})

task_log.status = 'FAILED'
task_log.detail = detail

Expand Down Expand Up @@ -113,6 +124,16 @@ def wrapper(*args):
})
if not payment:
all_details[0]['expense_group_id'] = expense_group.id
Error.objects.update_or_create(
workspace_id=expense_group.workspace_id,
expense_group=expense_group,
defaults={
'type': 'NETSUITE_ERROR',
'error_title': netsuite_error_message,
'error_detail': detail['message'],
'is_resolved': False
}
)
task_log.detail = all_details

task_log.save()
Expand All @@ -126,6 +147,17 @@ def wrapper(*args):
task_log.save()

except NetSuiteRateLimitError:
if not payment:
Error.objects.update_or_create(
workspace_id=expense_group.workspace_id,
expense_group=expense_group,
defaults={
'type': 'NETSUITE_ERROR',
'error_title': netsuite_error_message,
'error_detail': f'Rate limit error, workspace_id - {expense_group.workspace_id}',
'is_resolved': False
}
)
logger.info('Rate limit error, workspace_id - %s', workspace_id if payment else expense_group.workspace_id)
task_log.status = 'FAILED'
task_log.detail = {
Expand Down
48 changes: 48 additions & 0 deletions apps/netsuite/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,18 @@ def upload_attachments_and_update_export(expenses: List[Expense], task_log: Task
workspace_id, exception, traceback.format_exc()
)


def resolve_errors_for_exported_expense_group(expense_group, workspace_id=None):
"""
Resolve errors for exported expense group
:param expense_group: Expense group
"""
if isinstance(expense_group, list):
Error.objects.filter(workspace_id=workspace_id, expense_group_id__in=expense_group, is_resolved=False).update(is_resolved=True)
else:
Error.objects.filter(workspace_id=expense_group.workspace_id, expense_group=expense_group, is_resolved=False).update(is_resolved=True)


@handle_netsuite_exceptions(payment=False)
def create_bill(expense_group, task_log_id, last_export):
task_log = TaskLog.objects.get(id=task_log_id)
Expand Down Expand Up @@ -433,6 +445,7 @@ def create_bill(expense_group, task_log_id, last_export):
expense_group.exported_at = datetime.now()
expense_group.response_logs = created_bill
expense_group.save()
resolve_errors_for_exported_expense_group(expense_group)

task_log.save()

Expand Down Expand Up @@ -501,6 +514,7 @@ def create_credit_card_charge(expense_group, task_log_id, last_export):
expense_group.exported_at = datetime.now()
expense_group.response_logs = created_credit_card_charge
expense_group.save()
resolve_errors_for_exported_expense_group(expense_group)


@handle_netsuite_exceptions(payment=False)
Expand Down Expand Up @@ -545,6 +559,7 @@ def create_expense_report(expense_group, task_log_id, last_export):
expense_group.exported_at = datetime.now()
expense_group.response_logs = created_expense_report
expense_group.save()
resolve_errors_for_exported_expense_group(expense_group)

task_log.save()

Expand Down Expand Up @@ -592,6 +607,7 @@ def create_journal_entry(expense_group, task_log_id, last_export):
expense_group.exported_at = datetime.now()
expense_group.response_logs = created_journal_entry
expense_group.save()
resolve_errors_for_exported_expense_group(expense_group)

task_log.save()

Expand Down Expand Up @@ -730,6 +746,18 @@ def __validate_tax_group_mapping(expense_group: ExpenseGroup, configuration: Con
'message': 'Tax Group Mapping not found'
})

if tax_group:
Error.objects.update_or_create(
workspace_id=tax_group.workspace_id,
expense_attribute=tax_group,
defaults={
'type': 'TAX_MAPPING',
'error_title': tax_group.value,
'error_detail': 'Tax mapping is missing',
'is_resolved': False
}
)

row = row + 1

return bulk_errors
Expand Down Expand Up @@ -836,6 +864,12 @@ def __validate_category_mapping(expense_group: ExpenseGroup, configuration: Conf
workspace_id=expense_group.workspace_id
).first()

category_attribute = ExpenseAttribute.objects.filter(
value=category,
workspace_id=expense_group.workspace_id,
attribute_type='CATEGORY'
).first()

if category_mapping:
if expense_group.fund_source == 'PERSONAL':
if configuration.reimbursable_expenses_object == 'EXPENSE REPORT':
Expand All @@ -857,6 +891,19 @@ def __validate_category_mapping(expense_group: ExpenseGroup, configuration: Conf
'message': 'Category Mapping Not Found'
})

if category_attribute:
Error.objects.update_or_create(
workspace_id=expense_group.workspace_id,
expense_attribute=category_attribute,
defaults={
'type': 'CATEGORY_MAPPING',
'error_title': category_attribute.value,
'error_detail': 'Category mapping is missing',
'is_resolved': False
}
)


row = row + 1

return bulk_errors
Expand Down Expand Up @@ -1196,6 +1243,7 @@ def process_vendor_payment(entity_object, workspace_id, object_type):
task_log.status = 'COMPLETE'

task_log.save()
resolve_errors_for_exported_expense_group(expense_group_ids, workspace_id)


def create_vendor_payment(workspace_id):
Expand Down
61 changes: 60 additions & 1 deletion tests/test_mappings/test_signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,68 @@
from apps.workspaces.models import Configuration, Workspace
from apps.mappings.models import GeneralMapping
from apps.tasks.models import Error
from fyle_accounting_mappings.models import MappingSetting, ExpenseAttribute, EmployeeMapping
from fyle_accounting_mappings.models import MappingSetting, ExpenseAttribute, EmployeeMapping, CategoryMapping, Mapping


def test_resolve_post_mapping_errors(access_token):
tax_group = ExpenseAttribute.objects.filter(
value='GST: NCF-AU @0.0%',
workspace_id=1,
attribute_type='TAX_GROUP'
).first()

Error.objects.update_or_create(
workspace_id=1,
expense_attribute=tax_group,
defaults={
'type': 'TAX_GROUP_MAPPING',
'error_title': tax_group.value,
'error_detail': 'Tax group mapping is missing',
'is_resolved': False
}
)

mapping = Mapping(
source_type='TAX_GROUP',
destination_type='TAX_DETAIL',
# source__value=source_value,
source_id=1642,
destination_id=1019,
workspace_id=1
)
mapping.save()
error = Error.objects.filter(expense_attribute_id=mapping.source_id).first()

assert error.is_resolved == True

@pytest.mark.django_db()
def test_resolve_post_category_mapping_errors(access_token):
source_category = ExpenseAttribute.objects.filter(
id=96,
workspace_id=1,
attribute_type='CATEGORY'
).first()

Error.objects.update_or_create(
workspace_id=1,
expense_attribute=source_category,
defaults={
'type': 'CATEGORY_MAPPING',
'error_title': source_category.value,
'error_detail': 'Category mapping is missing',
'is_resolved': False
}
)
category_mapping, _ = CategoryMapping.objects.update_or_create(
source_category_id=96,
destination_account_id=791,
destination_expense_head_id=791,
workspace_id=1
)

error = Error.objects.filter(expense_attribute_id=category_mapping.source_category_id).first()
assert error.is_resolved == True

@pytest.mark.django_db()
def test_resolve_post_employees_mapping_errors(access_token):
source_employee = ExpenseAttribute.objects.filter(
Expand Down
20 changes: 20 additions & 0 deletions tests/test_mappings/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,26 @@ def test_resolve_expense_attribute_errors(db):
resolve_expense_attribute_errors('EMPLOYEE', workspace_id, 'VENDOR')
assert Error.objects.get(id=error.id).is_resolved == True

source_category = ExpenseAttribute.objects.filter(
id=34,
workspace_id=1,
attribute_type='CATEGORY'
).first()

error, _ = Error.objects.update_or_create(
workspace_id=1,
expense_attribute=source_category,
defaults={
'type': 'CATEGORY_MAPPING',
'error_title': source_category.value,
'error_detail': 'Category mapping is missing',
'is_resolved': False
}
)

resolve_expense_attribute_errors('CATEGORY', workspace_id, 'ACCOUNT')
assert Error.objects.get(id=error.id).is_resolved == True


def test_disable_category_for_items_mapping(db ,mocker):
workspace_id = 49
Expand Down

0 comments on commit 24fabfa

Please sign in to comment.