From 2fc9218fb760929d194381af9b87fc08e935e3c7 Mon Sep 17 00:00:00 2001 From: Ashutosh619-sudo Date: Thu, 14 Sep 2023 12:36:04 +0530 Subject: [PATCH] refactor background tasks --- apps/mappings/queue.py | 91 +++++++++++++++++++ apps/mappings/signals.py | 4 +- apps/mappings/tasks.py | 88 ------------------ apps/mappings/utils.py | 2 +- .../apis/advanced_settings/serializers.py | 2 +- .../apis/advanced_settings/triggers.py | 2 +- .../apis/export_settings/triggers.py | 2 +- .../apis/import_settings/triggers.py | 2 +- apps/workspaces/queue.py | 66 ++++++++++++++ apps/workspaces/tasks.py | 61 ------------- apps/workspaces/utils.py | 4 +- apps/xero/actions.py | 2 +- apps/xero/queue.py | 71 +++++++++++++++ apps/xero/tasks.py | 69 -------------- tests/test_mappings/test_tasks.py | 2 + tests/test_workspaces/test_tasks.py | 3 +- tests/test_xero/test_tasks.py | 1 + 17 files changed, 243 insertions(+), 229 deletions(-) create mode 100644 apps/mappings/queue.py create mode 100644 apps/workspaces/queue.py create mode 100644 apps/xero/queue.py diff --git a/apps/mappings/queue.py b/apps/mappings/queue.py new file mode 100644 index 00000000..dd2a3859 --- /dev/null +++ b/apps/mappings/queue.py @@ -0,0 +1,91 @@ +from django_q.models import Schedule +from datetime import datetime, timedelta +from fyle_accounting_mappings.models import MappingSetting + + +def schedule_auto_map_employees(employee_mapping_preference: str, workspace_id: str): + if employee_mapping_preference: + Schedule.objects.update_or_create( + func='apps.mappings.tasks.async_auto_map_employees', + args='{}'.format(workspace_id), + defaults={ + 'schedule_type': Schedule.MINUTES, + 'minutes': 24 * 60, + 'next_run': datetime.now() + } + ) + else: + schedule: Schedule = Schedule.objects.filter( + func='apps.mappings.tasks.async_auto_map_employees', + args='{}'.format(workspace_id) + ).first() + + if schedule: + schedule.delete() + + +def schedule_cost_centers_creation(import_to_fyle, workspace_id: int): + if import_to_fyle: + schedule, _ = Schedule.objects.update_or_create( + func='apps.mappings.tasks.auto_create_cost_center_mappings', + args='{}'.format(workspace_id), + defaults={ + 'schedule_type': Schedule.MINUTES, + 'minutes': 24 * 60, + 'next_run': datetime.now() + } + ) + else: + schedule: Schedule = Schedule.objects.filter( + func='apps.mappings.tasks.auto_create_cost_center_mappings', + args='{}'.format(workspace_id) + ).first() + + if schedule: + schedule.delete() + + +def schedule_tax_groups_creation(import_tax_codes, workspace_id): + if import_tax_codes: + schedule, _ = Schedule.objects.update_or_create( + func='apps.mappings.tasks.auto_create_tax_codes_mappings', + args='{}'.format(workspace_id), + defaults={ + 'schedule_type': Schedule.MINUTES, + 'minutes': 24 * 60, + 'next_run': datetime.now() + } + ) + else: + schedule: Schedule = Schedule.objects.filter( + func='apps.mappings.tasks.auto_create_tax_codes_mappings', + args='{}'.format(workspace_id), + ).first() + + if schedule: + schedule.delete() + + +def schedule_fyle_attributes_creation(workspace_id: int): + mapping_settings = MappingSetting.objects.filter( + is_custom=True, import_to_fyle=True, workspace_id=workspace_id + ).all() + + if mapping_settings: + schedule, _ = Schedule.objects.get_or_create( + func='apps.mappings.tasks.async_auto_create_custom_field_mappings', + args='{0}'.format(workspace_id), + defaults={ + 'schedule_type': Schedule.MINUTES, + 'minutes': 24 * 60, + 'next_run': datetime.now() + timedelta(hours=24) + } + ) + else: + schedule: Schedule = Schedule.objects.filter( + func='apps.mappings.tasks.async_auto_create_custom_field_mappings', + args=workspace_id + ).first() + + if schedule: + schedule.delete() diff --git a/apps/mappings/signals.py b/apps/mappings/signals.py index 7398d214..346a245b 100644 --- a/apps/mappings/signals.py +++ b/apps/mappings/signals.py @@ -11,8 +11,8 @@ from fyle_accounting_mappings.models import MappingSetting, ExpenseAttribute, Mapping from apps.tasks.models import Error -from apps.mappings.tasks import schedule_cost_centers_creation, schedule_fyle_attributes_creation,\ - upload_attributes_to_fyle +from apps.mappings.queue import schedule_cost_centers_creation, schedule_fyle_attributes_creation +from apps.mappings.tasks import upload_attributes_to_fyle from apps.workspaces.models import WorkspaceGeneralSettings from django.db.models.signals import post_save diff --git a/apps/mappings/tasks.py b/apps/mappings/tasks.py index c8be357d..26077e33 100644 --- a/apps/mappings/tasks.py +++ b/apps/mappings/tasks.py @@ -217,27 +217,6 @@ def async_auto_map_employees(workspace_id: int): resolve_expense_attribute_errors(source_attribute_type='EMPLOYEE', workspace_id=workspace_id) -def schedule_auto_map_employees(employee_mapping_preference: str, workspace_id: str): - if employee_mapping_preference: - Schedule.objects.update_or_create( - func='apps.mappings.tasks.async_auto_map_employees', - args='{}'.format(workspace_id), - defaults={ - 'schedule_type': Schedule.MINUTES, - 'minutes': 24 * 60, - 'next_run': datetime.now() - } - ) - else: - schedule: Schedule = Schedule.objects.filter( - func='apps.mappings.tasks.async_auto_map_employees', - args='{}'.format(workspace_id) - ).first() - - if schedule: - schedule.delete() - - def sync_xero_attributes(xero_attribute_type: str, workspace_id: int): xero_credentials: XeroCredentials = XeroCredentials.get_active_xero_credentials(workspace_id) xero_connection = XeroConnector( @@ -327,27 +306,6 @@ def auto_create_cost_center_mappings(workspace_id: int): post_cost_centers_in_batches(platform, workspace_id, mapping_setting.destination_field) -def schedule_cost_centers_creation(import_to_fyle, workspace_id: int): - if import_to_fyle: - schedule, _ = Schedule.objects.update_or_create( - func='apps.mappings.tasks.auto_create_cost_center_mappings', - args='{}'.format(workspace_id), - defaults={ - 'schedule_type': Schedule.MINUTES, - 'minutes': 24 * 60, - 'next_run': datetime.now() - } - ) - else: - schedule: Schedule = Schedule.objects.filter( - func='apps.mappings.tasks.auto_create_cost_center_mappings', - args='{}'.format(workspace_id) - ).first() - - if schedule: - schedule.delete() - - def create_fyle_projects_payload(projects: List[DestinationAttribute], existing_project_names: list, updated_projects: List[ExpenseAttribute] = None): """ @@ -595,31 +553,6 @@ def async_auto_create_custom_field_mappings(workspace_id: str): ) -def schedule_fyle_attributes_creation(workspace_id: int): - mapping_settings = MappingSetting.objects.filter( - is_custom=True, import_to_fyle=True, workspace_id=workspace_id - ).all() - - if mapping_settings: - schedule, _ = Schedule.objects.get_or_create( - func='apps.mappings.tasks.async_auto_create_custom_field_mappings', - args='{0}'.format(workspace_id), - defaults={ - 'schedule_type': Schedule.MINUTES, - 'minutes': 24 * 60, - 'next_run': datetime.now() + timedelta(hours=24) - } - ) - else: - schedule: Schedule = Schedule.objects.filter( - func='apps.mappings.tasks.async_auto_create_custom_field_mappings', - args=workspace_id - ).first() - - if schedule: - schedule.delete() - - def upload_tax_groups_to_fyle(platform_connection: PlatformConnector, workspace_id: int): existing_tax_codes_name = ExpenseAttribute.objects.filter( attribute_type='TAX_GROUP', workspace_id=workspace_id).values_list('value', flat=True) @@ -679,27 +612,6 @@ def auto_create_tax_codes_mappings(workspace_id: int): upload_tax_groups_to_fyle(platform, workspace_id) -def schedule_tax_groups_creation(import_tax_codes, workspace_id): - if import_tax_codes: - schedule, _ = Schedule.objects.update_or_create( - func='apps.mappings.tasks.auto_create_tax_codes_mappings', - args='{}'.format(workspace_id), - defaults={ - 'schedule_type': Schedule.MINUTES, - 'minutes': 24 * 60, - 'next_run': datetime.now() - } - ) - else: - schedule: Schedule = Schedule.objects.filter( - func='apps.mappings.tasks.auto_create_tax_codes_mappings', - args='{}'.format(workspace_id), - ).first() - - if schedule: - schedule.delete() - - def auto_create_suppliers_as_merchants(workspace_id): fyle_credentials: FyleCredential = FyleCredential.objects.get(workspace_id=workspace_id) fyle_connection = PlatformConnector(fyle_credentials) diff --git a/apps/mappings/utils.py b/apps/mappings/utils.py index 3ef9e2ce..cb9027ee 100644 --- a/apps/mappings/utils.py +++ b/apps/mappings/utils.py @@ -4,7 +4,7 @@ from fyle_xero_api.utils import assert_valid from .models import TenantMapping, GeneralMapping -from ..xero.tasks import schedule_payment_creation +from ..xero.queue import schedule_payment_creation class MappingUtils: diff --git a/apps/workspaces/apis/advanced_settings/serializers.py b/apps/workspaces/apis/advanced_settings/serializers.py index 358778b7..59f7622d 100644 --- a/apps/workspaces/apis/advanced_settings/serializers.py +++ b/apps/workspaces/apis/advanced_settings/serializers.py @@ -1,7 +1,7 @@ from rest_framework import serializers from apps.workspaces.models import Workspace, WorkspaceGeneralSettings, WorkspaceSchedule -from apps.workspaces.tasks import schedule_sync +from apps.workspaces.queue import schedule_sync from apps.mappings.models import GeneralMapping from .triggers import AdvancedSettingsTriggers diff --git a/apps/workspaces/apis/advanced_settings/triggers.py b/apps/workspaces/apis/advanced_settings/triggers.py index b0c5e0de..d094ffae 100644 --- a/apps/workspaces/apis/advanced_settings/triggers.py +++ b/apps/workspaces/apis/advanced_settings/triggers.py @@ -1,4 +1,4 @@ -from apps.xero.tasks import schedule_payment_creation, schedule_xero_objects_status_sync, schedule_reimbursements_sync +from apps.xero.queue import schedule_payment_creation, schedule_xero_objects_status_sync, schedule_reimbursements_sync from apps.workspaces.models import WorkspaceGeneralSettings diff --git a/apps/workspaces/apis/export_settings/triggers.py b/apps/workspaces/apis/export_settings/triggers.py index 6666c191..65f1e46a 100644 --- a/apps/workspaces/apis/export_settings/triggers.py +++ b/apps/workspaces/apis/export_settings/triggers.py @@ -1,4 +1,4 @@ -from apps.mappings.tasks import schedule_auto_map_employees +from apps.mappings.queue import schedule_auto_map_employees from apps.workspaces.models import WorkspaceGeneralSettings from fyle_accounting_mappings.models import MappingSetting from apps.workspaces.utils import delete_cards_mapping_settings, schedule_or_delete_import_supplier_schedule diff --git a/apps/workspaces/apis/import_settings/triggers.py b/apps/workspaces/apis/import_settings/triggers.py index a61c726c..e0710756 100644 --- a/apps/workspaces/apis/import_settings/triggers.py +++ b/apps/workspaces/apis/import_settings/triggers.py @@ -1,7 +1,7 @@ from typing import Dict, List from django.db.models import Q -from apps.mappings.tasks import schedule_cost_centers_creation, schedule_tax_groups_creation,\ +from apps.mappings.queue import schedule_cost_centers_creation, schedule_tax_groups_creation,\ schedule_fyle_attributes_creation from apps.mappings.helpers import schedule_or_delete_fyle_import_tasks from apps.workspaces.models import WorkspaceGeneralSettings diff --git a/apps/workspaces/queue.py b/apps/workspaces/queue.py new file mode 100644 index 00000000..fbb3d06f --- /dev/null +++ b/apps/workspaces/queue.py @@ -0,0 +1,66 @@ +from datetime import datetime, timedelta +from typing import List +from django_q.models import Schedule +from apps.workspaces.models import WorkspaceSchedule + + + +def schedule_email_notification(workspace_id: int, schedule_enabled: bool, hours: int): + if schedule_enabled: + schedule, _ = Schedule.objects.update_or_create( + func='apps.workspaces.tasks.run_email_notification', + args='{}'.format(workspace_id), + defaults={ + 'schedule_type': Schedule.MINUTES, + 'minutes': hours * 60, + 'next_run': datetime.now() + timedelta(minutes=10) + } + ) + else: + schedule: Schedule = Schedule.objects.filter( + func='apps.workspaces.tasks.run_email_notification', + args='{}'.format(workspace_id) + ).first() + + if schedule: + schedule.delete() + + +def schedule_sync(workspace_id: int, schedule_enabled: bool, hours: int, email_added: List, emails_selected: List): + ws_schedule, _ = WorkspaceSchedule.objects.get_or_create( + workspace_id=workspace_id + ) + + schedule_email_notification(workspace_id=workspace_id, schedule_enabled=schedule_enabled, hours=hours) + + if schedule_enabled: + ws_schedule.enabled = schedule_enabled + ws_schedule.start_datetime = datetime.now() + ws_schedule.interval_hours = hours + ws_schedule.emails_selected = emails_selected + + if email_added: + ws_schedule.additional_email_options.append(email_added) + + schedule, _ = Schedule.objects.update_or_create( + func='apps.workspaces.tasks.run_sync_schedule', + args='{}'.format(workspace_id), + defaults={ + 'schedule_type': Schedule.MINUTES, + 'minutes': hours * 60, + 'next_run': datetime.now() + } + ) + + ws_schedule.schedule = schedule + + ws_schedule.save() + + elif not schedule_enabled and ws_schedule.schedule: + schedule = ws_schedule.schedule + ws_schedule.enabled = schedule_enabled + ws_schedule.schedule = None + ws_schedule.save() + schedule.delete() + + return ws_schedule diff --git a/apps/workspaces/tasks.py b/apps/workspaces/tasks.py index d24055fe..7d6d936e 100644 --- a/apps/workspaces/tasks.py +++ b/apps/workspaces/tasks.py @@ -19,67 +19,6 @@ logger.level = logging.INFO -def schedule_email_notification(workspace_id: int, schedule_enabled: bool, hours: int): - if schedule_enabled: - schedule, _ = Schedule.objects.update_or_create( - func='apps.workspaces.tasks.run_email_notification', - args='{}'.format(workspace_id), - defaults={ - 'schedule_type': Schedule.MINUTES, - 'minutes': hours * 60, - 'next_run': datetime.now() + timedelta(minutes=10) - } - ) - else: - schedule: Schedule = Schedule.objects.filter( - func='apps.workspaces.tasks.run_email_notification', - args='{}'.format(workspace_id) - ).first() - - if schedule: - schedule.delete() - - -def schedule_sync(workspace_id: int, schedule_enabled: bool, hours: int, email_added: List, emails_selected: List): - ws_schedule, _ = WorkspaceSchedule.objects.get_or_create( - workspace_id=workspace_id - ) - - schedule_email_notification(workspace_id=workspace_id, schedule_enabled=schedule_enabled, hours=hours) - - if schedule_enabled: - ws_schedule.enabled = schedule_enabled - ws_schedule.start_datetime = datetime.now() - ws_schedule.interval_hours = hours - ws_schedule.emails_selected = emails_selected - - if email_added: - ws_schedule.additional_email_options.append(email_added) - - schedule, _ = Schedule.objects.update_or_create( - func='apps.workspaces.tasks.run_sync_schedule', - args='{}'.format(workspace_id), - defaults={ - 'schedule_type': Schedule.MINUTES, - 'minutes': hours * 60, - 'next_run': datetime.now() - } - ) - - ws_schedule.schedule = schedule - - ws_schedule.save() - - elif not schedule_enabled and ws_schedule.schedule: - schedule = ws_schedule.schedule - ws_schedule.enabled = schedule_enabled - ws_schedule.schedule = None - ws_schedule.save() - schedule.delete() - - return ws_schedule - - def run_sync_schedule(workspace_id): """ Run schedule diff --git a/apps/workspaces/utils.py b/apps/workspaces/utils.py index c1c113fb..1c35db13 100644 --- a/apps/workspaces/utils.py +++ b/apps/workspaces/utils.py @@ -15,8 +15,8 @@ from fyle_accounting_mappings.models import MappingSetting -from apps.mappings.tasks import schedule_auto_map_employees, schedule_tax_groups_creation -from apps.xero.tasks import schedule_payment_creation, schedule_xero_objects_status_sync, schedule_reimbursements_sync +from apps.mappings.queue import schedule_auto_map_employees, schedule_tax_groups_creation +from apps.xero.queue import schedule_payment_creation, schedule_xero_objects_status_sync, schedule_reimbursements_sync from fyle_xero_api.utils import assert_valid from .models import WorkspaceGeneralSettings, Workspace diff --git a/apps/xero/actions.py b/apps/xero/actions.py index f7750834..9e4b6956 100644 --- a/apps/xero/actions.py +++ b/apps/xero/actions.py @@ -41,7 +41,7 @@ def refersh_xero_dimension(workspace_id): for mapping_setting in mapping_settings: if mapping_setting.source_field == 'PROJECT': # run auto_import_and_map_fyle_fields - chain.append('apps.mappings.tasks.auto_import_and_map_fyle_fields', int(workspace_id)) + chain.append('apps.mappings.queue.auto_import_and_map_fyle_fields', int(workspace_id)) elif mapping_setting.source_field == 'COST_CENTER': # run auto_create_cost_center_mappings chain.append('apps.mappings.tasks.auto_create_cost_center_mappings', int(workspace_id)) diff --git a/apps/xero/queue.py b/apps/xero/queue.py new file mode 100644 index 00000000..941ab6c6 --- /dev/null +++ b/apps/xero/queue.py @@ -0,0 +1,71 @@ +from apps.mappings.models import GeneralMapping +from datetime import datetime, timedelta +from django_q.models import Schedule + +def schedule_payment_creation(sync_fyle_to_xero_payments, workspace_id): + general_mappings: GeneralMapping = GeneralMapping.objects.filter(workspace_id=workspace_id).first() + if general_mappings: + if sync_fyle_to_xero_payments and general_mappings.payment_account_id: + start_datetime = datetime.now() + schedule, _ = Schedule.objects.update_or_create( + func='apps.xero.tasks.create_payment', + args='{}'.format(workspace_id), + defaults={ + 'schedule_type': Schedule.MINUTES, + 'minutes': 24 * 60, + 'next_run': start_datetime + } + ) + if not sync_fyle_to_xero_payments: + schedule: Schedule = Schedule.objects.filter( + func='apps.xero.tasks.create_payment', + args='{}'.format(workspace_id) + ).first() + + if schedule: + schedule.delete() + + +def schedule_xero_objects_status_sync(sync_xero_to_fyle_payments, workspace_id): + if sync_xero_to_fyle_payments: + start_datetime = datetime.now() + schedule, _ = Schedule.objects.update_or_create( + func='apps.xero.tasks.check_xero_object_status', + args='{}'.format(workspace_id), + defaults={ + 'schedule_type': Schedule.MINUTES, + 'minutes': 24 * 60, + 'next_run': start_datetime + } + ) + else: + schedule: Schedule = Schedule.objects.filter( + func='apps.xero.tasks.check_xero_object_status', + args='{}'.format(workspace_id) + ).first() + + if schedule: + schedule.delete() + + +def schedule_reimbursements_sync(sync_xero_to_fyle_payments, workspace_id): + if sync_xero_to_fyle_payments: + start_datetime = datetime.now() + timedelta(hours=12) + schedule, _ = Schedule.objects.update_or_create( + func='apps.xero.tasks.process_reimbursements', + args='{}'.format(workspace_id), + defaults={ + 'schedule_type': Schedule.MINUTES, + 'minutes': 24 * 60, + 'next_run': start_datetime + } + ) + else: + schedule: Schedule = Schedule.objects.filter( + func='apps.xero.tasks.process_reimbursements', + args='{}'.format(workspace_id) + ).first() + + if schedule: + schedule.delete() + diff --git a/apps/xero/tasks.py b/apps/xero/tasks.py index 14f340dc..526ac4fa 100644 --- a/apps/xero/tasks.py +++ b/apps/xero/tasks.py @@ -6,7 +6,6 @@ from django.db import transaction from django.db.models import Q -from django_q.models import Schedule from django_q.tasks import Chain from fyle_accounting_mappings.models import Mapping, ExpenseAttribute, DestinationAttribute @@ -658,30 +657,6 @@ def create_payment(workspace_id): process_payments(bill,workspace_id,task_log, general_mappings) -def schedule_payment_creation(sync_fyle_to_xero_payments, workspace_id): - general_mappings: GeneralMapping = GeneralMapping.objects.filter(workspace_id=workspace_id).first() - if general_mappings: - if sync_fyle_to_xero_payments and general_mappings.payment_account_id: - start_datetime = datetime.now() - schedule, _ = Schedule.objects.update_or_create( - func='apps.xero.tasks.create_payment', - args='{}'.format(workspace_id), - defaults={ - 'schedule_type': Schedule.MINUTES, - 'minutes': 24 * 60, - 'next_run': start_datetime - } - ) - if not sync_fyle_to_xero_payments: - schedule: Schedule = Schedule.objects.filter( - func='apps.xero.tasks.create_payment', - args='{}'.format(workspace_id) - ).first() - - if schedule: - schedule.delete() - - def get_all_xero_bill_ids(xero_objects): xero_objects_details = {} @@ -740,28 +715,6 @@ def check_xero_object_status(workspace_id): ) -def schedule_xero_objects_status_sync(sync_xero_to_fyle_payments, workspace_id): - if sync_xero_to_fyle_payments: - start_datetime = datetime.now() - schedule, _ = Schedule.objects.update_or_create( - func='apps.xero.tasks.check_xero_object_status', - args='{}'.format(workspace_id), - defaults={ - 'schedule_type': Schedule.MINUTES, - 'minutes': 24 * 60, - 'next_run': start_datetime - } - ) - else: - schedule: Schedule = Schedule.objects.filter( - func='apps.xero.tasks.check_xero_object_status', - args='{}'.format(workspace_id) - ).first() - - if schedule: - schedule.delete() - - def process_reimbursements(workspace_id): fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) @@ -794,28 +747,6 @@ def process_reimbursements(workspace_id): platform.reimbursements.sync() -def schedule_reimbursements_sync(sync_xero_to_fyle_payments, workspace_id): - if sync_xero_to_fyle_payments: - start_datetime = datetime.now() + timedelta(hours=12) - schedule, _ = Schedule.objects.update_or_create( - func='apps.xero.tasks.process_reimbursements', - args='{}'.format(workspace_id), - defaults={ - 'schedule_type': Schedule.MINUTES, - 'minutes': 24 * 60, - 'next_run': start_datetime - } - ) - else: - schedule: Schedule = Schedule.objects.filter( - func='apps.xero.tasks.process_reimbursements', - args='{}'.format(workspace_id) - ).first() - - if schedule: - schedule.delete() - - def create_missing_currency(workspace_id: int): """ Create missing currency in Xero diff --git a/tests/test_mappings/test_tasks.py b/tests/test_mappings/test_tasks.py index 6f762e4b..873785b7 100644 --- a/tests/test_mappings/test_tasks.py +++ b/tests/test_mappings/test_tasks.py @@ -3,6 +3,7 @@ from django_q.models import Schedule from fyle_accounting_mappings.models import DestinationAttribute, CategoryMapping, \ Mapping, MappingSetting, EmployeeMapping +from apps.mappings.queue import * from apps.mappings.tasks import * from fyle_integrations_platform_connector import PlatformConnector from fyle.platform.exceptions import InvalidTokenError as FyleInvalidTokenError, InternalServerError @@ -11,6 +12,7 @@ from .fixtures import data from tests.helper import dict_compare_keys from apps.fyle.models import ExpenseGroup, Reimbursement, Expense +from fyle_accounting_mappings.models import ExpenseAttribute from apps.workspaces.models import XeroCredentials, FyleCredential, WorkspaceGeneralSettings from xerosdk.exceptions import WrongParamsError, UnsuccessfulAuthentication diff --git a/tests/test_workspaces/test_tasks.py b/tests/test_workspaces/test_tasks.py index 0d0f362d..21668716 100644 --- a/tests/test_workspaces/test_tasks.py +++ b/tests/test_workspaces/test_tasks.py @@ -2,7 +2,8 @@ from apps.tasks.models import TaskLog from apps.workspaces.email import send_failure_notification_email from apps.workspaces.tasks import run_email_notification, run_sync_schedule, \ - schedule_sync, async_update_fyle_credentials, async_add_admins_to_workspace + async_update_fyle_credentials, async_add_admins_to_workspace +from apps.workspaces.queue import schedule_sync from apps.workspaces.models import WorkspaceSchedule, WorkspaceGeneralSettings, LastExportDetail, \ FyleCredential from apps.users.models import User diff --git a/tests/test_xero/test_tasks.py b/tests/test_xero/test_tasks.py index 92603004..9ac90d80 100644 --- a/tests/test_xero/test_tasks.py +++ b/tests/test_xero/test_tasks.py @@ -5,6 +5,7 @@ from apps.tasks.models import TaskLog from apps.xero.models import Bill, BillLineItem, BankTransaction, BankTransactionLineItem from apps.xero.tasks import * +from apps.xero.queue import * from apps.xero.tasks import __validate_expense_group from xerosdk.exceptions import XeroSDKError, WrongParamsError, InvalidGrant, RateLimitError, NoPrivilegeError from fyle_accounting_mappings.models import Mapping, ExpenseAttribute