Skip to content

Commit

Permalink
fix: improve response times of sync/refresh dimensions requests (#661)
Browse files Browse the repository at this point in the history
* fix(apps/qbo): delegate sync dimensions tasks to workers

* fix(apps/fyle): delegate sync dimensions tasks to workers

* fix: respond with a 400 for invalid workspaces/creds

* refactor: linting

* test: add unit tests for functions that have been made async
  • Loading branch information
1 parent bbd9ef0 commit 349e2f7
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 8 deletions.
18 changes: 14 additions & 4 deletions apps/fyle/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import logging

from apps.fyle.helpers import ExpenseGroupSearchFilter, ExpenseSearchFilter

from apps.workspaces.models import FyleCredential, Workspace
from django_filters.rest_framework import DjangoFilterBackend
from django_q.tasks import async_task
from rest_framework import generics
from rest_framework.response import Response
from rest_framework.views import status
Expand All @@ -11,8 +14,6 @@
get_custom_fields,
get_expense_fields,
get_expense_group_ids,
refresh_fyle_dimension,
sync_fyle_dimensions,
)
from apps.fyle.models import Expense, ExpenseFilter, ExpenseGroup, ExpenseGroupSettings
from apps.fyle.queue import async_import_and_export_expenses
Expand Down Expand Up @@ -120,7 +121,12 @@ def post(self, request, *args, **kwargs):
"""
Sync Data From Fyle
"""
sync_fyle_dimensions(workspace_id=kwargs['workspace_id'])

# Check for a valid workspace and fyle creds and respond with 400 if not found
Workspace.objects.get(id=kwargs['workspace_id'])
FyleCredential.objects.get(workspace_id=kwargs['workspace_id'])

async_task('apps.fyle.actions.sync_fyle_dimensions', kwargs['workspace_id'])

return Response(status=status.HTTP_200_OK)

Expand All @@ -136,7 +142,11 @@ def post(self, request, *args, **kwargs):
Sync data from Fyle
"""

refresh_fyle_dimension(workspace_id=kwargs['workspace_id'])
# Check for a valid workspace and fyle creds and respond with 400 if not found
Workspace.objects.get(id=kwargs['workspace_id'])
FyleCredential.objects.get(workspace_id=kwargs['workspace_id'])

async_task('apps.fyle.actions.refresh_fyle_dimension', kwargs['workspace_id'])

return Response(status=status.HTTP_200_OK)

Expand Down
18 changes: 15 additions & 3 deletions apps/quickbooks_online/views.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import logging

from django.db.models import Q
from apps.workspaces.models import QBOCredential, Workspace
from django_filters.rest_framework import DjangoFilterBackend
from django_q.tasks import async_task
from fyle_accounting_mappings.models import DestinationAttribute
from fyle_accounting_mappings.serializers import DestinationAttributeSerializer
from rest_framework import generics
from rest_framework.response import Response
from rest_framework.views import status

from apps.exceptions import handle_view_exceptions
from apps.quickbooks_online.actions import get_preferences, refresh_quickbooks_dimensions, sync_quickbooks_dimensions
from apps.quickbooks_online.actions import get_preferences
from fyle_qbo_api.utils import LookupFieldMixin

from .serializers import QuickbooksFieldSerializer
Expand Down Expand Up @@ -73,7 +75,12 @@ class SyncQuickbooksDimensionView(generics.ListCreateAPIView):

@handle_view_exceptions()
def post(self, request, *args, **kwargs):
sync_quickbooks_dimensions(kwargs['workspace_id'])

# Check for a valid workspace and qbo creds and respond with 400 if not found
Workspace.objects.get(id=kwargs['workspace_id'])
QBOCredential.get_active_qbo_credentials(kwargs['workspace_id'])

async_task('apps.quickbooks_online.actions.sync_quickbooks_dimensions', kwargs['workspace_id'])

return Response(status=status.HTTP_200_OK)

Expand All @@ -88,7 +95,12 @@ def post(self, request, *args, **kwargs):
"""
Sync data from quickbooks
"""
refresh_quickbooks_dimensions(kwargs['workspace_id'])

# Check for a valid workspace and qbo creds and respond with 400 if not found
Workspace.objects.get(id=kwargs['workspace_id'])
QBOCredential.get_active_qbo_credentials(kwargs['workspace_id'])

async_task('apps.quickbooks_online.actions.refresh_quickbooks_dimensions', kwargs['workspace_id'])

return Response(status=status.HTTP_200_OK)

Expand Down
27 changes: 27 additions & 0 deletions tests/test_fyle/test_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from apps.fyle.models import Expense, ExpenseGroup
from apps.fyle.actions import (
refresh_fyle_dimension,
sync_fyle_dimensions,
update_expenses_in_progress,
mark_expenses_as_skipped,
mark_accounting_export_summary_as_synced,
Expand Down Expand Up @@ -164,3 +166,28 @@ def test_handle_post_accounting_export_summary_exception(db):
settings.QBO_INTEGRATION_APP_URL
)
assert expense.accounting_export_summary['id'] == expense_id


def test_sync_fyle_dimensions(db):
workspace = Workspace.objects.get(id=3)

with mock.patch('fyle_integrations_platform_connector.fyle_integrations_platform_connector.PlatformConnector.import_fyle_dimensions') as mock_call:
mock_call.return_value = None

sync_fyle_dimensions(3)
assert workspace.source_synced_at is not None

# If dimensions were synced ≤ 1 day ago, they shouldn't be synced again
old_source_synced_at = workspace.source_synced_at
sync_fyle_dimensions(3)
assert workspace.source_synced_at == old_source_synced_at


def test_refresh_fyle_dimension(db):
workspace = Workspace.objects.get(id=3)

with mock.patch('fyle_integrations_platform_connector.fyle_integrations_platform_connector.PlatformConnector.import_fyle_dimensions') as mock_call:
mock_call.return_value = None

refresh_fyle_dimension(3)
assert workspace.source_synced_at is not None
30 changes: 29 additions & 1 deletion tests/test_quickbooks_online/test_actions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from unittest import mock
from apps.fyle.models import ExpenseGroup
from apps.quickbooks_online.actions import generate_export_url_and_update_expense
from apps.quickbooks_online.actions import generate_export_url_and_update_expense, refresh_quickbooks_dimensions, sync_quickbooks_dimensions
from apps.workspaces.models import Workspace


def test_generate_export_url_and_update_expense(db):
Expand All @@ -14,3 +16,29 @@ def test_generate_export_url_and_update_expense(db):
assert expense.accounting_export_summary['error_type'] == None
assert expense.accounting_export_summary['id'] == expense.expense_id
assert expense.accounting_export_summary['state'] == 'COMPLETE'


def test_refresh_quickbooks_dimensions(db):
workspace_id = 1
workspace = Workspace.objects.get(id=3)

with mock.patch('apps.quickbooks_online.utils.QBOConnector.sync_dimensions') as mock_call:
mock_call.return_value = None

refresh_quickbooks_dimensions(workspace_id)
assert workspace.destination_synced_at is not None


def test_sync_quickbooks_dimensions(db):
workspace = Workspace.objects.get(id=3)

with mock.patch('apps.quickbooks_online.utils.QBOConnector.sync_dimensions') as mock_call:
mock_call.return_value = None

sync_quickbooks_dimensions(3)
assert workspace.destination_synced_at is not None

# If dimensions were synced ≤ 1 day ago, they shouldn't be synced again
old_destination_synced_at = workspace.destination_synced_at
sync_quickbooks_dimensions(3)
assert workspace.destination_synced_at == old_destination_synced_at

0 comments on commit 349e2f7

Please sign in to comment.