Skip to content

Commit

Permalink
fix qbo creds inactive exports (#646)
Browse files Browse the repository at this point in the history
* fix qbo creds inactive exports

* move condition to start of func, add test cases

* remove refresh token once qbo creds expire
  • Loading branch information
Hrishabh17 committed Jul 15, 2024
1 parent 924c189 commit e6875dc
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 1 deletion.
8 changes: 8 additions & 0 deletions apps/quickbooks_online/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ def new_fn(*args):
detail = {'expense_group_id': expense_group.id, 'message': 'QBO Account not connected / token expired'}
task_log.status = 'FAILED'
task_log.detail = detail
qbo_credentials = QBOCredential.objects.filter(
workspace_id=expense_group.workspace_id
).first()

if qbo_credentials:
qbo_credentials.is_expired = True
qbo_credentials.refresh_token = None
qbo_credentials.save()

task_log.save()

Expand Down
9 changes: 9 additions & 0 deletions apps/workspaces/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,15 @@ def post_to_integration_settings(workspace_id: int, active: bool):


def export_to_qbo(workspace_id, export_mode=None, expense_group_ids=[]):
active_qbo_credentials = QBOCredential.objects.filter(
workspace_id=workspace_id,
is_expired=False,
refresh_token__isnull=False
).first()

if not active_qbo_credentials:
return

general_settings = WorkspaceGeneralSettings.objects.get(workspace_id=workspace_id)
last_export_detail = LastExportDetail.objects.get(workspace_id=workspace_id)
workspace_schedule = WorkspaceSchedule.objects.filter(workspace_id=workspace_id, interval_hours__gt=0, enabled=True).first()
Expand Down
37 changes: 37 additions & 0 deletions tests/test_quickbooks_online/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ def test_create_bill_exceptions(db, create_task_logs):
expense.save()

expense_group.expenses.set(expenses)
qbo_credentials = QBOCredential.objects.filter(workspace_id=expense_group.workspace_id).first()

with mock.patch('apps.quickbooks_online.models.Bill.create_bill') as mock_call:
mock_call.side_effect = QBOCredential.DoesNotExist()
Expand All @@ -181,18 +182,24 @@ def test_create_bill_exceptions(db, create_task_logs):
task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FAILED'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = BulkError(msg='employess not found', response='mapping error')
create_bill(expense_group, task_log.id, True)

task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FAILED'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = Exception()
create_bill(expense_group, task_log.id, False)

task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FATAL'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = WrongParamsError(msg={'Message': 'Invalid parametrs'}, response=json.dumps({'Fault': {'Error': [{'code': 400, 'Message': 'Invalid parametrs', 'Detail': 'Invalid parametrs'}], 'type': 'Invalid_params'}}))
create_bill(expense_group, task_log.id, False)

Expand Down Expand Up @@ -383,6 +390,7 @@ def test_post_qbo_expenses_exceptions(create_task_logs, db):
qbo_expense_lineitem = QBOExpenseLineitem.objects.get(expense_id=7)
qbo_expense_lineitem.expense_id = 24
qbo_expense_lineitem.save()
qbo_credentials = QBOCredential.objects.filter(workspace_id=expense_group.workspace_id).first()

with mock.patch('apps.quickbooks_online.models.QBOExpense.create_qbo_expense') as mock_call:
mock_call.side_effect = QBOCredential.DoesNotExist()
Expand All @@ -391,18 +399,24 @@ def test_post_qbo_expenses_exceptions(create_task_logs, db):
task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FAILED'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = BulkError(msg='employess not found', response='mapping error')
create_qbo_expense(expense_group, task_log.id, False)

task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FAILED'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = Exception()
create_qbo_expense(expense_group, task_log.id, False)

task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FATAL'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = WrongParamsError(msg={'Message': 'Invalid parametrs'}, response=json.dumps({'Fault': {'Error': [{'code': 400, 'Message': 'Invalid parametrs', 'Detail': 'Invalid parametrs'}], 'type': 'Invalid_params'}}))
create_qbo_expense(expense_group, task_log.id, False)

Expand Down Expand Up @@ -464,6 +478,7 @@ def test_post_credit_card_exceptions(mocker, create_task_logs, db):
expense.save()

expense_group.expenses.set(expenses)
qbo_credentials = QBOCredential.objects.filter(workspace_id=expense_group.workspace_id).first()

with mock.patch('apps.quickbooks_online.models.CreditCardPurchase.create_credit_card_purchase') as mock_call:
mock_call.side_effect = QBOCredential.DoesNotExist()
Expand All @@ -472,18 +487,24 @@ def test_post_credit_card_exceptions(mocker, create_task_logs, db):
task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FAILED'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = BulkError(msg='employess not found', response='mapping error')
create_credit_card_purchase(expense_group, task_log.id, False)

task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FAILED'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = Exception()
create_credit_card_purchase(expense_group, task_log.id, False)

task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FATAL'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = WrongParamsError(msg={'Message': 'Invalid parametrs'}, response=json.dumps({'Fault': {'Error': [{'code': 400, 'Message': 'Invalid parametrs', 'Detail': 'Invalid parametrs'}], 'type': 'Invalid_params'}}))
create_credit_card_purchase(expense_group, task_log.id, False)

Expand Down Expand Up @@ -567,25 +588,33 @@ def test_post_create_journal_entry_exceptions(create_task_logs, db):
expense_group.expenses.set(expenses)
expense_group.save()

qbo_credentials = QBOCredential.objects.filter(workspace_id=expense_group.workspace_id).first()

with mock.patch('apps.quickbooks_online.models.JournalEntry.create_journal_entry') as mock_call:
mock_call.side_effect = QBOCredential.DoesNotExist()
create_journal_entry(expense_group, task_log.id, False)

task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FAILED'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = BulkError(msg='employess not found', response='mapping error')
create_journal_entry(expense_group, task_log.id, False)

task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FAILED'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = Exception()
create_journal_entry(expense_group, task_log.id, False)

task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FATAL'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = WrongParamsError(msg={'Message': 'Invalid parametrs'}, response=json.dumps({'Fault': {'Error': [{'code': 400, 'Message': 'Invalid parametrs', 'Detail': 'Invalid parametrs'}], 'type': 'Invalid_params'}}))
create_journal_entry(expense_group, task_log.id, False)

Expand Down Expand Up @@ -636,25 +665,33 @@ def test_post_create_cheque_exceptions(create_task_logs, db):
expense_group.expenses.set(expenses)
expense_group.save()

qbo_credentials = QBOCredential.objects.filter(workspace_id=expense_group.workspace_id).first()

with mock.patch('apps.quickbooks_online.models.Cheque.create_cheque') as mock_call:
mock_call.side_effect = QBOCredential.DoesNotExist()
create_cheque(expense_group, task_log.id, False)

task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FAILED'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = BulkError(msg='employess not found', response='mapping error')
create_cheque(expense_group, task_log.id, False)

task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FAILED'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = Exception()
create_cheque(expense_group, task_log.id, False)

task_log = TaskLog.objects.get(id=task_log.id)
assert task_log.status == 'FATAL'

qbo_credentials.is_expired = False
qbo_credentials.save()
mock_call.side_effect = WrongParamsError(msg={'Message': 'Invalid parametrs'}, response=json.dumps({'Fault': {'Error': [{'code': 400, 'Message': 'Invalid parametrs', 'Detail': 'Invalid parametrs'}], 'type': 'Invalid_params'}}))
create_cheque(expense_group, task_log.id, False)

Expand Down
23 changes: 22 additions & 1 deletion tests/test_workspaces/test_views.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import json
from unittest import mock
from datetime import datetime, timedelta

from django.urls import reverse
from qbosdk import exceptions as qbo_exc

from apps.workspaces.models import QBOCredential, Workspace, WorkspaceGeneralSettings
from apps.workspaces.models import QBOCredential, Workspace, WorkspaceGeneralSettings, LastExportDetail
from fyle_qbo_api.tests import settings
from tests.helper import dict_compare_keys
from tests.test_workspaces.fixtures import data
from apps.workspaces.actions import export_to_qbo
from apps.fyle.models import ExpenseGroup


def test_get_workspace(api_client, test_connection):
Expand Down Expand Up @@ -201,6 +204,24 @@ def test_export_to_qbo(mocker, api_client, test_connection):
response = api_client.post(url)
assert response.status_code == 200

ExpenseGroup.objects.filter(workspace_id=workspace_id).update(exported_at=None)
expense_group_ids = ExpenseGroup.objects.filter(workspace_id=workspace_id).values_list('id', flat=True)

qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id)
assert qbo_credentials is not None
assert len(expense_group_ids) != 0
export_to_qbo(workspace_id, expense_group_ids=expense_group_ids)
last_export_detail = LastExportDetail.objects.get(workspace_id=workspace_id)
last_exported_at = last_export_detail.last_exported_at
assert last_exported_at.replace(tzinfo=None) > (datetime.now() - timedelta(minutes=1)).replace(tzinfo=None)

qbo_credentials.is_expired = True
qbo_credentials.save()

export_to_qbo(workspace_id, expense_group_ids=expense_group_ids)
last_export_detail = LastExportDetail.objects.get(workspace_id=workspace_id)
assert last_export_detail.last_exported_at == last_exported_at


def test_last_export_detail_view(db, api_client, test_connection):
workspace_id = 3
Expand Down

0 comments on commit e6875dc

Please sign in to comment.