From bcbb759405d155f83008c61d30893bfc7d7cbd3a Mon Sep 17 00:00:00 2001 From: labhvam5 Date: Wed, 8 Nov 2023 13:05:09 +0530 Subject: [PATCH] Adding scheduling logic --- apps/mappings/helpers.py | 16 ++++- apps/mappings/{queue.py => queues.py} | 60 ++++++++++++++++++- apps/mappings/schedules.py | 42 +++++++++++++ apps/mappings/signals.py | 6 +- apps/mappings/tasks.py | 4 -- .../apis/advanced_configurations/triggers.py | 2 +- .../apis/export_settings/triggers.py | 2 +- .../apis/import_settings/triggers.py | 2 +- apps/workspaces/utils.py | 2 +- tests/test_mappings/test_tasks.py | 2 +- tests/test_quickbooks_online/test_tasks.py | 2 +- 11 files changed, 124 insertions(+), 16 deletions(-) rename apps/mappings/{queue.py => queues.py} (69%) create mode 100644 apps/mappings/schedules.py diff --git a/apps/mappings/helpers.py b/apps/mappings/helpers.py index 8c7215bc..dd19ab56 100644 --- a/apps/mappings/helpers.py +++ b/apps/mappings/helpers.py @@ -11,9 +11,19 @@ def schedule_or_delete_fyle_import_tasks(configuration: WorkspaceGeneralSettings :param configuration: WorkspaceGeneralSettings Instance :return: None """ - project_mapping = MappingSetting.objects.filter(source_field='PROJECT', workspace_id=configuration.workspace_id).first() - if configuration.import_categories or configuration.import_items or (project_mapping and project_mapping.import_to_fyle) or configuration.import_vendors_as_merchants: + if configuration.import_categories or configuration.import_items or configuration.import_vendors_as_merchants: start_datetime = datetime.now() Schedule.objects.update_or_create(func='apps.mappings.tasks.auto_import_and_map_fyle_fields', args='{}'.format(configuration.workspace_id), defaults={'schedule_type': Schedule.MINUTES, 'minutes': 24 * 60, 'next_run': start_datetime}) - elif not configuration.import_categories and not configuration.import_items and not (project_mapping and project_mapping.import_to_fyle) and not configuration.import_vendors_as_merchants: + elif not configuration.import_categories and not configuration.import_items and not configuration.import_vendors_as_merchants: Schedule.objects.filter(func='apps.mappings.tasks.auto_import_and_map_fyle_fields', args='{}'.format(configuration.workspace_id)).delete() + +def get_auto_sync_permission(mapping_setting: MappingSetting): + """ + Get the auto sync permission + :return: bool + """ + is_auto_sync_status_allowed = False + if (mapping_setting.destination_field == 'PROJECT' and mapping_setting.source_field == 'CUSTOMER') or mapping_setting.source_field == 'CATEGORY': + is_auto_sync_status_allowed = True + + return is_auto_sync_status_allowed \ No newline at end of file diff --git a/apps/mappings/queue.py b/apps/mappings/queues.py similarity index 69% rename from apps/mappings/queue.py rename to apps/mappings/queues.py index f7186ebe..1467887e 100644 --- a/apps/mappings/queue.py +++ b/apps/mappings/queues.py @@ -5,7 +5,18 @@ from fyle_accounting_mappings.models import MappingSetting from apps.mappings.models import GeneralMapping -from apps.workspaces.models import WorkspaceGeneralSettings +from apps.workspaces.models import WorkspaceGeneralSettings, QBOCredential +from apps.mappings.helpers import get_auto_sync_permission + +SYNC_METHODS = { + 'ACCOUNT': 'accounts', + 'ITEM': 'items', + 'VENDOR': 'vendors', + 'DEPARTMENT': 'departments', + 'TAX_CODE': 'tax_codes', + 'CLASS': 'classes', + 'CUSTOMER': 'customers', +} def async_auto_create_expense_field_mapping(mapping_setting: MappingSetting): @@ -86,3 +97,50 @@ def schedule_auto_map_employees(employee_mapping_preference: str, workspace_id: def async_disable_category_for_items_mapping(workspace_id: int): async_task('apps.mappings.tasks.disable_category_for_items_mapping', workspace_id) + + +def construct_task_settings_payload(workspace_id): + """ + Chain import fields to Fyle + :param workspace_id: Workspace Id + """ + mapping_settings = MappingSetting.objects.filter(workspace_id=workspace_id, import_to_fyle=True) + credentials = QBOCredential.objects.get(workspace_id=workspace_id) + + task_settings = { + 'import_tax_codes': { + 'destination_field': '', + 'destination_sync_method': '', + 'is_auto_sync_enabled' : False, + 'import': False, + }, + 'import_vendors_as_merchants': { + 'destination_field': '', + 'destination_sync_method': '', + 'is_auto_sync_enabled' : False, + 'import': False, + }, + 'import_categories': { + 'destination_field': '', + 'destination_sync_method': '', + 'is_auto_sync_enabled' : False, + 'import': False, + }, + 'mapping_settings': [], + 'credentails': credentials, + 'sdk_connection_string': 'apps.quickbooks_online.utils.QBOConnector', + } + + for mapping_setting in mapping_settings: + if mapping_setting.source_field in ['PROJECT']: + task_settings['mapping_settings'].append({ + 'source_field': mapping_setting.source_field, + 'destination_field': mapping_setting.destination_field, + 'destination_sync_method': SYNC_METHODS[mapping_setting.destination_field], + 'is_auto_sync_enabled' : get_auto_sync_permission(mapping_setting), + 'is_custom': False, + }) + + # Make a call to the SDK + # chain_import_fields_to_fyle(workspace_id, task_settings) + pass diff --git a/apps/mappings/schedules.py b/apps/mappings/schedules.py new file mode 100644 index 00000000..f2705a3e --- /dev/null +++ b/apps/mappings/schedules.py @@ -0,0 +1,42 @@ +from datetime import datetime +from django_q.models import Schedule +from apps.workspaces.models import WorkspaceGeneralSettings +from fyle_accounting_mappings.models import MappingSetting + + +def schedule_or_delete_fyle_import_tasks(workspace_general_settings: WorkspaceGeneralSettings, mapping_setting_instance: MappingSetting = None): + """ + Schedule or delete Fyle import tasks based on the configuration. + :param configuration: Workspace Configuration Instance + :param instance: Mapping Setting Instance + :return: None + """ + task_to_be_scheduled = None + # Check if there is a task to be scheduled + if mapping_setting_instance and mapping_setting_instance.import_to_fyle: + task_to_be_scheduled = mapping_setting_instance + + if task_to_be_scheduled: + Schedule.objects.update_or_create( + func='apps.mappings.queue.construct_task_settings_payload', + args='{}'.format(workspace_general_settings.workspace_id), + defaults={ + 'schedule_type': Schedule.MINUTES, + 'minutes': 24 * 60, + 'next_run': datetime.now() + } + ) + return + + import_fields_count = MappingSetting.objects.filter( + import_to_fyle=True, + workspace_id=workspace_general_settings.workspace_id, + source_field__in=['PROJECT'] + ).count() + + # If the import fields count is 0, delete the schedule + if import_fields_count == 0: + Schedule.objects.filter( + func='apps.mappings.queue.construct_task_settings_payload', + args='{}'.format(workspace_general_settings.workspace_id) + ).delete() diff --git a/apps/mappings/signals.py b/apps/mappings/signals.py index 9c6fa1bf..255df117 100644 --- a/apps/mappings/signals.py +++ b/apps/mappings/signals.py @@ -6,12 +6,14 @@ from fyle_accounting_mappings.models import EmployeeMapping, Mapping, MappingSetting from apps.mappings.helpers import schedule_or_delete_fyle_import_tasks -from apps.mappings.queue import ( +from apps.mappings.queues import ( async_auto_create_expense_field_mapping, schedule_cost_centers_creation, schedule_fyle_attributes_creation, ) from apps.mappings.tasks import upload_attributes_to_fyle +# TODO: Fix the naming convention when we remove the old schedule_or_delete_fyle_import_tasks import from helpers.py +from apps.mappings.schedules import schedule_or_delete_fyle_import_tasks as new_schedule_or_delete_fyle_import_tasks from apps.tasks.models import Error from apps.workspaces.apis.import_settings.triggers import ImportSettingsTrigger from apps.workspaces.models import WorkspaceGeneralSettings @@ -51,7 +53,7 @@ def run_post_mapping_settings_triggers(sender, instance: MappingSetting, **kwarg workspace_general_settings = WorkspaceGeneralSettings.objects.filter(workspace_id=instance.workspace_id).first() if instance.source_field == 'PROJECT': - schedule_or_delete_fyle_import_tasks(workspace_general_settings) + new_schedule_or_delete_fyle_import_tasks(workspace_general_settings, instance) if instance.source_field == 'COST_CENTER': schedule_cost_centers_creation(instance.import_to_fyle, int(instance.workspace_id)) diff --git a/apps/mappings/tasks.py b/apps/mappings/tasks.py index 59d31f07..09a05cdf 100644 --- a/apps/mappings/tasks.py +++ b/apps/mappings/tasks.py @@ -786,7 +786,6 @@ def auto_import_and_map_fyle_fields(workspace_id): Auto import and map fyle fields """ workspace_general_settings: WorkspaceGeneralSettings = WorkspaceGeneralSettings.objects.get(workspace_id=workspace_id) - project_mapping = MappingSetting.objects.filter(source_field='PROJECT', workspace_id=workspace_general_settings.workspace_id).first() chain = Chain() @@ -796,8 +795,5 @@ def auto_import_and_map_fyle_fields(workspace_id): if workspace_general_settings.import_categories or workspace_general_settings.import_items: chain.append('apps.mappings.tasks.auto_create_category_mappings', workspace_id) - if project_mapping and project_mapping.import_to_fyle: - chain.append('apps.mappings.tasks.auto_create_project_mappings', workspace_id) - if chain.length() > 0: chain.run() diff --git a/apps/workspaces/apis/advanced_configurations/triggers.py b/apps/workspaces/apis/advanced_configurations/triggers.py index 0b391e53..8fb6f393 100644 --- a/apps/workspaces/apis/advanced_configurations/triggers.py +++ b/apps/workspaces/apis/advanced_configurations/triggers.py @@ -1,6 +1,6 @@ import logging -from apps.mappings.queue import schedule_bill_payment_creation +from apps.mappings.queues import schedule_bill_payment_creation from apps.quickbooks_online.queue import schedule_qbo_objects_status_sync, schedule_reimbursements_sync from apps.workspaces.models import WorkspaceGeneralSettings from apps.workspaces.actions import post_to_integration_settings diff --git a/apps/workspaces/apis/export_settings/triggers.py b/apps/workspaces/apis/export_settings/triggers.py index 1a2c7ed9..6288625a 100644 --- a/apps/workspaces/apis/export_settings/triggers.py +++ b/apps/workspaces/apis/export_settings/triggers.py @@ -1,6 +1,6 @@ from typing import Dict -from apps.mappings.queue import async_disable_category_for_items_mapping +from apps.mappings.queues import async_disable_category_for_items_mapping from apps.workspaces.models import WorkspaceGeneralSettings diff --git a/apps/workspaces/apis/import_settings/triggers.py b/apps/workspaces/apis/import_settings/triggers.py index 2a36862f..2fffb89e 100644 --- a/apps/workspaces/apis/import_settings/triggers.py +++ b/apps/workspaces/apis/import_settings/triggers.py @@ -5,7 +5,7 @@ from apps.fyle.models import ExpenseGroupSettings from apps.mappings.helpers import schedule_or_delete_fyle_import_tasks -from apps.mappings.queue import ( +from apps.mappings.queues import ( async_disable_category_for_items_mapping, schedule_cost_centers_creation, schedule_fyle_attributes_creation, diff --git a/apps/workspaces/utils.py b/apps/workspaces/utils.py index 5648547e..039cd9ae 100644 --- a/apps/workspaces/utils.py +++ b/apps/workspaces/utils.py @@ -9,7 +9,7 @@ from qbosdk import InternalServerError, NotFoundClientError, UnauthorizedClientError, WrongParamsError from apps.fyle.models import ExpenseGroupSettings -from apps.mappings.queue import ( +from apps.mappings.queues import ( schedule_auto_map_ccc_employees, schedule_auto_map_employees, schedule_bill_payment_creation, diff --git a/tests/test_mappings/test_tasks.py b/tests/test_mappings/test_tasks.py index 9759d6c9..4fc3ff76 100644 --- a/tests/test_mappings/test_tasks.py +++ b/tests/test_mappings/test_tasks.py @@ -13,7 +13,7 @@ from fyle_integrations_platform_connector import PlatformConnector from qbosdk.exceptions import WrongParamsError -from apps.mappings.queue import ( +from apps.mappings.queues import ( schedule_auto_map_ccc_employees, schedule_auto_map_employees, schedule_cost_centers_creation, diff --git a/tests/test_quickbooks_online/test_tasks.py b/tests/test_quickbooks_online/test_tasks.py index ac66ea6d..8adfa2ae 100644 --- a/tests/test_quickbooks_online/test_tasks.py +++ b/tests/test_quickbooks_online/test_tasks.py @@ -8,7 +8,7 @@ from qbosdk.exceptions import WrongParamsError from apps.fyle.models import Expense, ExpenseGroup, Reimbursement -from apps.mappings.queue import schedule_bill_payment_creation +from apps.mappings.queues import schedule_bill_payment_creation from apps.quickbooks_online.exceptions import handle_quickbooks_error from apps.quickbooks_online.queue import ( schedule_bills_creation,