From 19ef313536a587207a3023570d0f8314501ac404 Mon Sep 17 00:00:00 2001 From: labhvam5 Date: Wed, 20 Dec 2023 12:48:13 +0530 Subject: [PATCH 1/4] ImportTax + Vendors : Scheduling --- apps/mappings/helpers.py | 15 --------------- apps/mappings/queues.py | 10 ---------- apps/mappings/schedules.py | 19 +++++++------------ .../apis/import_settings/triggers.py | 8 -------- apps/workspaces/utils.py | 5 +---- 5 files changed, 8 insertions(+), 49 deletions(-) diff --git a/apps/mappings/helpers.py b/apps/mappings/helpers.py index 5fbf1227..c0e543d1 100644 --- a/apps/mappings/helpers.py +++ b/apps/mappings/helpers.py @@ -1,23 +1,8 @@ -from datetime import datetime - -from django_q.models import Schedule from fyle_accounting_mappings.models import MappingSetting from apps.workspaces.models import WorkspaceGeneralSettings -def schedule_or_delete_fyle_import_tasks(configuration: WorkspaceGeneralSettings): - """ - :param configuration: WorkspaceGeneralSettings Instance - :return: None - """ - if 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}) - else: - Schedule.objects.filter(func='apps.mappings.tasks.auto_import_and_map_fyle_fields', args='{}'.format(configuration.workspace_id)).delete() - - def get_auto_sync_permission(workspace_general_settings: WorkspaceGeneralSettings, mapping_setting: MappingSetting = None): """ Get the auto sync permission diff --git a/apps/mappings/queues.py b/apps/mappings/queues.py index b4f2f4d1..2a93a49d 100644 --- a/apps/mappings/queues.py +++ b/apps/mappings/queues.py @@ -38,16 +38,6 @@ def schedule_auto_map_ccc_employees(workspace_id: int): 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_auto_map_employees(employee_mapping_preference: str, workspace_id: int): if employee_mapping_preference: start_datetime = datetime.now() diff --git a/apps/mappings/schedules.py b/apps/mappings/schedules.py index 4a76fe7e..c1f911dc 100644 --- a/apps/mappings/schedules.py +++ b/apps/mappings/schedules.py @@ -14,11 +14,12 @@ def schedule_or_delete_fyle_import_tasks(workspace_general_settings: WorkspaceGe """ task_to_be_scheduled = None for mapping_setting in mapping_settings: - if mapping_setting['import_to_fyle'] and mapping_setting['source_field'] in ['PROJECT', 'COST_CENTER'] or mapping_setting['is_custom']: + if mapping_setting['import_to_fyle']: task_to_be_scheduled = True break - if task_to_be_scheduled or workspace_general_settings.import_categories or workspace_general_settings.import_items: + if task_to_be_scheduled or workspace_general_settings.import_categories or workspace_general_settings.import_items\ + or workspace_general_settings.import_tax_codes or workspace_general_settings.import_vendors_as_merchants: Schedule.objects.update_or_create( func='apps.mappings.queues.construct_tasks_and_chain_import_fields_to_fyle', args='{}'.format(workspace_general_settings.workspace_id), @@ -32,19 +33,13 @@ def schedule_or_delete_fyle_import_tasks(workspace_general_settings: WorkspaceGe else: import_fields_count = MappingSetting.objects.filter( import_to_fyle=True, - workspace_id=workspace_general_settings.workspace_id, - source_field__in=['PROJECT', 'COST_CENTER'] - ).count() - - custom_field_import_fields_count = MappingSetting.objects.filter( - import_to_fyle=True, - workspace_id=workspace_general_settings.workspace_id, - is_custom=True + workspace_id=workspace_general_settings.workspace_id ).count() # If the import fields count is 0, delete the schedule - if import_fields_count == 0 and custom_field_import_fields_count == 0\ - and not workspace_general_settings.import_categories and not workspace_general_settings.import_items: + if import_fields_count == 0\ + and not workspace_general_settings.import_categories and not workspace_general_settings.import_items\ + and not workspace_general_settings.import_tax_codes and not workspace_general_settings.import_vendors_as_merchants: Schedule.objects.filter( func='apps.mappings.queues.construct_tasks_and_chain_import_fields_to_fyle', args='{}'.format(workspace_general_settings.workspace_id) diff --git a/apps/workspaces/apis/import_settings/triggers.py b/apps/workspaces/apis/import_settings/triggers.py index c9e7f862..91d7f540 100644 --- a/apps/workspaces/apis/import_settings/triggers.py +++ b/apps/workspaces/apis/import_settings/triggers.py @@ -4,10 +4,6 @@ from fyle_accounting_mappings.models import MappingSetting from apps.fyle.models import ExpenseGroupSettings -from apps.mappings.helpers import schedule_or_delete_fyle_import_tasks -from apps.mappings.queues import ( - schedule_tax_groups_creation -) from apps.workspaces.models import WorkspaceGeneralSettings from apps.mappings.schedules import schedule_or_delete_fyle_import_tasks as new_schedule_or_delete_fyle_import_tasks @@ -76,9 +72,6 @@ def post_save_workspace_general_settings(self, workspace_general_settings_instan """ Post save action for workspace general settings """ - schedule_tax_groups_creation(import_tax_codes=self.__workspace_general_settings.get('import_tax_codes'), workspace_id=self.__workspace_id) - - schedule_or_delete_fyle_import_tasks(workspace_general_settings_instance) new_schedule_or_delete_fyle_import_tasks(workspace_general_settings_instance) def __remove_old_department_source_field(self, current_mappings_settings: List[MappingSetting], new_mappings_settings: List[Dict]): @@ -116,4 +109,3 @@ def post_save_mapping_settings(self, workspace_general_settings_instance: Worksp self.__update_expense_group_settings_for_departments() new_schedule_or_delete_fyle_import_tasks(workspace_general_settings_instance, self.__mapping_settings) - schedule_or_delete_fyle_import_tasks(workspace_general_settings_instance) diff --git a/apps/workspaces/utils.py b/apps/workspaces/utils.py index 039cd9ae..527ed775 100644 --- a/apps/workspaces/utils.py +++ b/apps/workspaces/utils.py @@ -12,8 +12,7 @@ from apps.mappings.queues import ( schedule_auto_map_ccc_employees, schedule_auto_map_employees, - schedule_bill_payment_creation, - schedule_tax_groups_creation, + schedule_bill_payment_creation ) from apps.quickbooks_online.queue import schedule_qbo_objects_status_sync, schedule_reimbursements_sync from apps.workspaces.models import WorkspaceGeneralSettings @@ -136,8 +135,6 @@ def create_or_update_general_settings(general_settings_payload: Dict, workspace_ expense_group_settings.import_card_credits = True expense_group_settings.save() - schedule_tax_groups_creation(import_tax_codes=general_settings.import_tax_codes, workspace_id=workspace_id) - schedule_auto_map_employees(general_settings_payload['auto_map_employees'], workspace_id) schedule_auto_map_ccc_employees(workspace_id) From e0479308c6c98cce53701fc5b86dd527e3e27edd Mon Sep 17 00:00:00 2001 From: labhvam5 Date: Wed, 20 Dec 2023 16:48:17 +0530 Subject: [PATCH 2/4] resolving comments --- apps/mappings/schedules.py | 4 +--- fyle_integrations_imports | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/mappings/schedules.py b/apps/mappings/schedules.py index c1f911dc..b11bc23e 100644 --- a/apps/mappings/schedules.py +++ b/apps/mappings/schedules.py @@ -37,9 +37,7 @@ def schedule_or_delete_fyle_import_tasks(workspace_general_settings: WorkspaceGe ).count() # If the import fields count is 0, delete the schedule - if import_fields_count == 0\ - and not workspace_general_settings.import_categories and not workspace_general_settings.import_items\ - and not workspace_general_settings.import_tax_codes and not workspace_general_settings.import_vendors_as_merchants: + if import_fields_count == 0: Schedule.objects.filter( func='apps.mappings.queues.construct_tasks_and_chain_import_fields_to_fyle', args='{}'.format(workspace_general_settings.workspace_id) diff --git a/fyle_integrations_imports b/fyle_integrations_imports index 8ffc4ec3..b78722ad 160000 --- a/fyle_integrations_imports +++ b/fyle_integrations_imports @@ -1 +1 @@ -Subproject commit 8ffc4ec3cb6f7fb9d1f1fb0e8edf3c09b9a14c29 +Subproject commit b78722ad1ec78bff96a0624fbfe20b68b4a562af From a853188b33199a5d04b6745bb37845f0187c3068 Mon Sep 17 00:00:00 2001 From: labhvam5 <88420539+labhvam5@users.noreply.github.com> Date: Fri, 22 Dec 2023 16:48:36 +0530 Subject: [PATCH 3/4] implementation (#544) * implementation * adding tax condition * resolving comments * Removing old code (#545) * Removing old code * Adding test (#546) * resolving comments * resolving comments * adding test * removing dead code * removing dead code * fixing import * Migration script (#547) * Migration script * combining scripts into one --- apps/mappings/queues.py | 16 + apps/mappings/signals.py | 2 +- apps/mappings/tasks.py | 168 +------ apps/workspaces/actions.py | 2 +- .../apis/import_settings/triggers.py | 2 +- apps/workspaces/utils.py | 108 ----- ...ate-new-tax-groups-and-merchants-import.py | 48 ++ .../test_modules/fixtures.py | 457 ++++++++++++++++++ .../test_modules/test_merchants.py | 172 +++++++ .../test_modules/test_tax_groups.py | 195 ++++++++ tests/test_mappings/test_tasks.py | 150 +----- 11 files changed, 896 insertions(+), 424 deletions(-) create mode 100644 scripts/python/create-update-new-tax-groups-and-merchants-import.py create mode 100644 tests/test_fyle_integrations_imports/test_modules/test_merchants.py create mode 100644 tests/test_fyle_integrations_imports/test_modules/test_tax_groups.py diff --git a/apps/mappings/queues.py b/apps/mappings/queues.py index 2a93a49d..5361f50e 100644 --- a/apps/mappings/queues.py +++ b/apps/mappings/queues.py @@ -84,6 +84,22 @@ def construct_tasks_and_chain_import_fields_to_fyle(workspace_id): 'charts_of_accounts': workspace_general_settings.charts_of_accounts if 'accounts' in destination_sync_methods else None, } + if workspace_general_settings.import_tax_codes: + task_settings['import_tax'] = { + 'destination_field': 'TAX_CODE', + 'destination_sync_methods': [SYNC_METHODS['TAX_CODE']], + 'is_auto_sync_enabled': get_auto_sync_permission(workspace_general_settings), + 'is_3d_mapping': False, + } + + if workspace_general_settings.import_vendors_as_merchants: + task_settings['import_vendors_as_merchants'] = { + 'destination_field': 'VENDOR', + 'destination_sync_methods': [SYNC_METHODS['VENDOR']], + 'is_auto_sync_enabled': get_auto_sync_permission(workspace_general_settings), + 'is_3d_mapping': False, + } + if not workspace_general_settings.import_items: task_settings['import_items'] = False diff --git a/apps/mappings/signals.py b/apps/mappings/signals.py index 2cb71e1e..cd18ea9e 100644 --- a/apps/mappings/signals.py +++ b/apps/mappings/signals.py @@ -26,7 +26,7 @@ def resolve_post_mapping_errors(sender, instance: Mapping, **kwargs): """ Resolve errors after mapping is created """ - if instance.source_type in ('CATEGORY', 'TAX_GROUP'): + if instance.source_type in ('CATEGORY'): error = Error.objects.filter(expense_attribute_id=instance.source_id).first() if error: error.is_resolved = True diff --git a/apps/mappings/tasks.py b/apps/mappings/tasks.py index 5ea59a34..61ad1436 100644 --- a/apps/mappings/tasks.py +++ b/apps/mappings/tasks.py @@ -1,8 +1,7 @@ import logging -from typing import Dict, List +from typing import List -from django_q.tasks import Chain -from fyle_accounting_mappings.models import DestinationAttribute, EmployeeMapping, ExpenseAttribute, Mapping, MappingSetting +from fyle_accounting_mappings.models import DestinationAttribute, EmployeeMapping, ExpenseAttribute from fyle_integrations_platform_connector import PlatformConnector from apps.mappings.exceptions import handle_import_exceptions @@ -14,29 +13,6 @@ logger = logging.getLogger(__name__) logger.level = logging.INFO -DEFAULT_FYLE_CATEGORIES = [ - 'train', - 'fuel', - 'office supplies', - 'utility', - 'entertainment', - 'others', - 'mileage', - 'food', - 'per diem', - 'bus', - 'taxi', - 'mail', - 'lodging', - 'professional services', - 'airlines', - 'software', - 'parking', - 'unspecified', - 'rental', - 'groceries', -] - def resolve_expense_attribute_errors(source_attribute_type: str, workspace_id: int, destination_attribute_type: str = None): """ @@ -48,10 +24,7 @@ def resolve_expense_attribute_errors(source_attribute_type: str, workspace_id: i if errored_attribute_ids: mapped_attribute_ids = [] - if source_attribute_type in ('TAX_GROUP'): - mapped_attribute_ids: List[int] = Mapping.objects.filter(source_id__in=errored_attribute_ids).values_list('source_id', flat=True) - - elif source_attribute_type == 'EMPLOYEE': + if source_attribute_type == 'EMPLOYEE': if destination_attribute_type == 'EMPLOYEE': params = {'source_employee_id__in': errored_attribute_ids, 'destination_employee_id__isnull': False} else: @@ -62,38 +35,6 @@ def resolve_expense_attribute_errors(source_attribute_type: str, workspace_id: i Error.objects.filter(expense_attribute_id__in=mapped_attribute_ids).update(is_resolved=True) -def remove_duplicates(qbo_attributes: List[DestinationAttribute]): - unique_attributes = [] - - attribute_values = [] - - for attribute in qbo_attributes: - if attribute.value.lower() not in attribute_values: - unique_attributes.append(attribute) - attribute_values.append(attribute.value.lower()) - - return unique_attributes - - -@handle_import_exceptions(task_name='Auto Create Tax Code Mappings') -def auto_create_tax_codes_mappings(workspace_id: int): - """ - Create Tax Codes Mappings - :return: None - """ - - fyle_credentials: FyleCredential = FyleCredential.objects.get(workspace_id=workspace_id) - - platform = PlatformConnector(fyle_credentials) - - platform.tax_groups.sync() - - mapping_setting = MappingSetting.objects.get(source_field='TAX_GROUP', workspace_id=workspace_id) - - sync_qbo_attribute(mapping_setting.destination_field, workspace_id) - upload_tax_groups_to_fyle(platform, workspace_id) - - def get_existing_source_and_mappings(destination_type: str, workspace_id: int): existing_mappings = EmployeeMapping.objects.filter(workspace_id=workspace_id).all() @@ -318,106 +259,3 @@ def async_auto_map_ccc_account(workspace_id: int): platform.employees.sync() auto_map_ccc_employees(default_ccc_account_id, workspace_id) - - -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) - - qbo_attributes = DestinationAttribute.objects.filter(attribute_type='TAX_CODE', workspace_id=workspace_id).order_by('value', 'id') - - qbo_attributes = remove_duplicates(qbo_attributes) - - fyle_payload: List[Dict] = create_fyle_tax_group_payload(qbo_attributes, existing_tax_codes_name) - - if fyle_payload: - platform_connection.tax_groups.post_bulk(fyle_payload) - - platform_connection.tax_groups.sync() - Mapping.bulk_create_mappings(qbo_attributes, 'TAX_GROUP', 'TAX_CODE', workspace_id) - resolve_expense_attribute_errors(source_attribute_type='TAX_GROUP', workspace_id=workspace_id) - - -def sync_qbo_attribute(qbo_attribute_type: str, workspace_id: int): - qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) - qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) - - if qbo_attribute_type == 'CUSTOMER': - qbo_connection.sync_customers() - - elif qbo_attribute_type == 'DEPARTMENT': - qbo_connection.sync_departments() - - elif qbo_attribute_type == 'CLASS': - qbo_connection.sync_classes() - - elif qbo_attribute_type == 'TAX_CODE': - qbo_connection.sync_tax_codes() - - elif qbo_attribute_type == 'VENDOR': - qbo_connection.sync_vendors() - - -def create_fyle_tax_group_payload(qbo_attributes: List[DestinationAttribute], existing_fyle_tax_groups: list): - """ - Create Fyle Cost Centers Payload from QBO Objects - :param existing_fyle_tax_groups: Existing cost center names - :param qbo_attributes: QBO Objects - :return: Fyle Cost Centers Payload - """ - - fyle_tax_group_payload = [] - for qbo_attribute in qbo_attributes: - if qbo_attribute.value not in existing_fyle_tax_groups: - fyle_tax_group_payload.append({'name': qbo_attribute.value, 'is_enabled': True, 'percentage': round((qbo_attribute.detail['tax_rate'] / 100), 2)}) - - return fyle_tax_group_payload - - -def create_fyle_merchants_payload(vendors, existing_merchants_name): - payload: List[str] = [] - for vendor in vendors: - if vendor.value not in existing_merchants_name: - payload.append(vendor.value) - - return payload - - -def post_merchants(platform_connection: PlatformConnector, workspace_id: int): - existing_merchants_name = ExpenseAttribute.objects.filter(attribute_type='MERCHANT', workspace_id=workspace_id).values_list('value', flat=True) - - qbo_attributes = DestinationAttribute.objects.filter(attribute_type='VENDOR', active=True, workspace_id=workspace_id).order_by('value', 'id') - - qbo_attributes = remove_duplicates(qbo_attributes) - - fyle_payload: List[str] = create_fyle_merchants_payload(qbo_attributes, existing_merchants_name) - - if fyle_payload: - platform_connection.merchants.post(fyle_payload) - platform_connection.merchants.sync() - - -@handle_import_exceptions(task_name='Auto Create Vendors as Merchants') -def auto_create_vendors_as_merchants(workspace_id): - fyle_credentials: FyleCredential = FyleCredential.objects.get(workspace_id=workspace_id) - - fyle_connection = PlatformConnector(fyle_credentials) - - fyle_connection.merchants.sync() - - sync_qbo_attribute('VENDOR', workspace_id) - post_merchants(fyle_connection, workspace_id) - - -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) - - chain = Chain() - - if workspace_general_settings.import_vendors_as_merchants: - chain.append('apps.mappings.tasks.auto_create_vendors_as_merchants', workspace_id) - - if chain.length() > 0: - chain.run() diff --git a/apps/workspaces/actions.py b/apps/workspaces/actions.py index fe424ab9..6034818a 100644 --- a/apps/workspaces/actions.py +++ b/apps/workspaces/actions.py @@ -28,7 +28,7 @@ from apps.workspaces.models import FyleCredential, LastExportDetail, QBOCredential, Workspace, WorkspaceGeneralSettings from apps.workspaces.serializers import QBOCredentialSerializer from apps.workspaces.signals import post_delete_qbo_connection -from apps.workspaces.utils import assert_valid +from fyle_qbo_api.utils import assert_valid User = get_user_model() logger = logging.getLogger(__name__) diff --git a/apps/workspaces/apis/import_settings/triggers.py b/apps/workspaces/apis/import_settings/triggers.py index 91d7f540..7f659e51 100644 --- a/apps/workspaces/apis/import_settings/triggers.py +++ b/apps/workspaces/apis/import_settings/triggers.py @@ -104,7 +104,7 @@ def post_save_mapping_settings(self, workspace_general_settings_instance: Worksp for setting in self.__mapping_settings: destination_fields.append(setting['destination_field']) - MappingSetting.objects.filter(~Q(destination_field__in=destination_fields), destination_field__in=['CLASS', 'CUSTOMER', 'DEPARTMENT'], workspace_id=self.__workspace_id).delete() + MappingSetting.objects.filter(~Q(destination_field__in=destination_fields), destination_field__in=['CLASS', 'CUSTOMER', 'DEPARTMENT', 'TAX_CODE'], workspace_id=self.__workspace_id).delete() self.__update_expense_group_settings_for_departments() diff --git a/apps/workspaces/utils.py b/apps/workspaces/utils.py index 527ed775..5ed031c8 100644 --- a/apps/workspaces/utils.py +++ b/apps/workspaces/utils.py @@ -1,6 +1,5 @@ import base64 import json -from typing import Dict import requests from django.conf import settings @@ -8,15 +7,7 @@ from fyle_accounting_mappings.models import MappingSetting from qbosdk import InternalServerError, NotFoundClientError, UnauthorizedClientError, WrongParamsError -from apps.fyle.models import ExpenseGroupSettings -from apps.mappings.queues import ( - schedule_auto_map_ccc_employees, - schedule_auto_map_employees, - 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 fyle_qbo_api.utils import assert_valid def generate_qbo_refresh_token(authorization_code: str, redirect_uri: str) -> str: @@ -49,105 +40,6 @@ def generate_qbo_refresh_token(authorization_code: str, redirect_uri: str) -> st raise InternalServerError('Internal server error', response.text) -def create_or_update_general_settings(general_settings_payload: Dict, workspace_id): - """ - Create or update general settings - :param workspace_id: - :param general_settings_payload: general settings payload - :return: - """ - assert_valid('reimbursable_expenses_object' in general_settings_payload and general_settings_payload['reimbursable_expenses_object'], 'reimbursable_expenses_object field is blank') - - assert_valid('employee_field_mapping' in general_settings_payload and general_settings_payload['employee_field_mapping'], 'employee_field_mapping field is blank') - - if 'auto_map_employees' in general_settings_payload and general_settings_payload['auto_map_employees']: - assert_valid(general_settings_payload['auto_map_employees'] in ['EMAIL', 'NAME', 'EMPLOYEE_CODE'], 'auto_map_employees can have only EMAIL / NAME / EMPLOYEE_CODE') - - if general_settings_payload['auto_create_destination_entity']: - assert_valid(general_settings_payload['auto_map_employees'] and general_settings_payload['employee_field_mapping'] == 'VENDOR', 'auto_create_destination_entity can be set only if auto map is enabled and employee mapped to vendor') - - if general_settings_payload['je_single_credit_line']: - assert_valid( - general_settings_payload['reimbursable_expenses_object'] == 'JOURNAL ENTRY' or general_settings_payload['corporate_credit_card_expenses_object'] == 'JOURNAL ENTRY', - 'je_single_credit_line can be set only if reimbursable_expenses_object or \ - corporate_credit_card_expenses_object is JOURNAL ENTRY', - ) - - if general_settings_payload['sync_fyle_to_qbo_payments'] or general_settings_payload['sync_qbo_to_fyle_payments']: - assert_valid( - general_settings_payload['reimbursable_expenses_object'] == 'BILL', - 'sync_fyle_to_qbo_payments / sync_qbo_to_fyle_payments can be set \ - only if reimbursable_expenses_object is BILL', - ) - - workspace_general_settings = WorkspaceGeneralSettings.objects.filter(workspace_id=workspace_id).first() - - map_merchant_to_vendor = True - - if workspace_general_settings: - map_merchant_to_vendor = workspace_general_settings.map_merchant_to_vendor - - # TODO: remove this hack once workspace settings are saved - if workspace_id == 98: - category_sync_version = 'v1' - else: - category_sync_version = workspace_general_settings.category_sync_version if workspace_general_settings else 'v2' - - general_settings, _ = WorkspaceGeneralSettings.objects.update_or_create( - workspace_id=workspace_id, - category_sync_version=category_sync_version, - defaults={ - 'employee_field_mapping': general_settings_payload['employee_field_mapping'], - 'import_projects': general_settings_payload['import_projects'], - 'import_categories': general_settings_payload['import_categories'], - 'import_tax_codes': general_settings_payload['import_tax_codes'], - 'change_accounting_period': general_settings_payload['change_accounting_period'], - 'charts_of_accounts': general_settings_payload['charts_of_accounts'], - 'auto_map_employees': general_settings_payload['auto_map_employees'], - 'auto_create_destination_entity': general_settings_payload['auto_create_destination_entity'], - 'auto_create_merchants_as_vendors': general_settings_payload['auto_create_merchants_as_vendors'], - 'reimbursable_expenses_object': general_settings_payload['reimbursable_expenses_object'] if 'reimbursable_expenses_object' in general_settings_payload and general_settings_payload['reimbursable_expenses_object'] else None, - 'corporate_credit_card_expenses_object': general_settings_payload['corporate_credit_card_expenses_object'] - if 'corporate_credit_card_expenses_object' in general_settings_payload and general_settings_payload['corporate_credit_card_expenses_object'] - else None, - 'sync_fyle_to_qbo_payments': general_settings_payload['sync_fyle_to_qbo_payments'], - 'sync_qbo_to_fyle_payments': general_settings_payload['sync_qbo_to_fyle_payments'], - 'map_merchant_to_vendor': map_merchant_to_vendor, - 'je_single_credit_line': general_settings_payload['je_single_credit_line'], - 'map_fyle_cards_qbo_account': general_settings_payload['map_fyle_cards_qbo_account'], - 'import_vendors_as_merchants': general_settings_payload['import_vendors_as_merchants'], - }, - ) - - if general_settings.map_merchant_to_vendor and general_settings.corporate_credit_card_expenses_object in ('CREDIT CARD PURCHASE', 'DEBIT CARD EXPENSE'): - expense_group_settings = ExpenseGroupSettings.objects.get(workspace_id=workspace_id) - expense_group_settings.import_card_credits = True if general_settings.corporate_credit_card_expenses_object == 'CREDIT CARD PURCHASE' else False - - ccc_expense_group_fields = expense_group_settings.corporate_credit_card_expense_group_fields - ccc_expense_group_fields.append('expense_id') - expense_group_settings.corporate_credit_card_expense_group_fields = list(set(ccc_expense_group_fields)) - expense_group_settings.ccc_export_date_type = 'spent_at' - - expense_group_settings.save() - - if general_settings.corporate_credit_card_expenses_object == 'JOURNAL ENTRY' or general_settings.reimbursable_expenses_object in ('JOURNAL ENTRY', 'EXPENSE'): - expense_group_settings = ExpenseGroupSettings.objects.get(workspace_id=workspace_id) - expense_group_settings.import_card_credits = True - expense_group_settings.save() - - schedule_auto_map_employees(general_settings_payload['auto_map_employees'], workspace_id) - - schedule_auto_map_ccc_employees(workspace_id) - - schedule_bill_payment_creation(general_settings.sync_fyle_to_qbo_payments, workspace_id) - - schedule_qbo_objects_status_sync(sync_qbo_to_fyle_payments=general_settings.sync_qbo_to_fyle_payments, workspace_id=workspace_id) - - schedule_reimbursements_sync(sync_qbo_to_fyle_payments=general_settings.sync_qbo_to_fyle_payments, workspace_id=workspace_id) - - return general_settings - - def delete_cards_mapping_settings(workspace_general_settings: WorkspaceGeneralSettings): if not workspace_general_settings.map_fyle_cards_qbo_account or not workspace_general_settings.corporate_credit_card_expenses_object: mapping_setting = MappingSetting.objects.filter(workspace_id=workspace_general_settings.workspace_id, source_field='CORPORATE_CARD', destination_field='CREDIT_CARD_ACCOUNT').first() diff --git a/scripts/python/create-update-new-tax-groups-and-merchants-import.py b/scripts/python/create-update-new-tax-groups-and-merchants-import.py new file mode 100644 index 00000000..a79ef34d --- /dev/null +++ b/scripts/python/create-update-new-tax-groups-and-merchants-import.py @@ -0,0 +1,48 @@ +from django.db import transaction +import random +from datetime import datetime, timedelta +from django_q.models import Schedule +from apps.workspaces.models import WorkspaceGeneralSettings + +existing_import_enabled_schedules = Schedule.objects.filter( + func__in=['apps.mappings.tasks.auto_create_tax_codes_mappings', 'apps.mappings.tasks.auto_import_and_map_fyle_fields'] +).values('args') + +try: + with transaction.atomic(): + for schedule in existing_import_enabled_schedules: + random_number = random.randint(1, 23) + workspace_general_settings = WorkspaceGeneralSettings.objects.get(workspace_id=schedule['args']) + if workspace_general_settings.import_tax_codes or workspace_general_settings.import_vendors_as_merchants: + print('Creating schedule for workspace_id: ', schedule['args']) + # adding the new schedule + Schedule.objects.update_or_create( + func='apps.mappings.queues.construct_tasks_and_chain_import_fields_to_fyle', + args=schedule['args'], + defaults={ + 'schedule_type': Schedule.MINUTES, + 'minutes':24 * 60, + 'next_run':datetime.now() + timedelta(hours=random_number) + } + ) + if workspace_general_settings.import_tax_codes: + # deleting the old tax schedule + Schedule.objects.filter( + func='apps.mappings.tasks.auto_create_tax_codes_mappings', + args=schedule['args'] + ).delete() + if workspace_general_settings.import_vendors_as_merchants: + # deleting the old merchants schedule + Schedule.objects.filter( + func='apps.mappings.tasks.auto_import_and_map_fyle_fields', + args=schedule['args'] + ).delete() + # remove this sanity check after running this script + raise Exception("This is a sanity check") +except Exception as e: + print(e) + + +# Run this in sql +# select * from django_q_schedule where func in ('apps.mappings.tasks.auto_create_tax_codes_mappings', 'apps.mappings.tasks.auto_import_and_map_fyle_fields'); +# --rows should be 0 diff --git a/tests/test_fyle_integrations_imports/test_modules/fixtures.py b/tests/test_fyle_integrations_imports/test_modules/fixtures.py index cc58c755..d5212526 100644 --- a/tests/test_fyle_integrations_imports/test_modules/fixtures.py +++ b/tests/test_fyle_integrations_imports/test_modules/fixtures.py @@ -8241,3 +8241,460 @@ 'code':None } } + +tax_groups_data = { + "create_new_auto_create_tax_groups_destination_attributes": [ + { + "SyncToken": "0", + "domain": "QBO", + "TaxGroup": True, + "Name": "California", + "Taxable": True, + "PurchaseTaxRateList": {"TaxRateDetail": [{"TaxRateRef": {"value": "6", "name": "ON TAX PURCHASE"}, "TaxTypeApplicable": "TaxOnAmount", "TaxOrder": 0}]}, + "sparse": False, + "Active": True, + "Description": "California", + "MetaData": {"CreateTime": "2014-09-18T12:17:04-07:00", "LastUpdatedTime": "2014-09-18T12:17:04-07:00"}, + "Id": "2", + "SalesTaxRateList": {"TaxRateDetail": [{"TaxTypeApplicable": "TaxOnAmount", "TaxRateRef": {"name": "California", "value": "3"}, "TaxOrder": 0}]}, + } + ], + "create_new_auto_create_tax_groups_destination_attributes_get_by_id": { + "RateValue": 2, + "AgencyRef": {"value": "1"}, + "domain": "QBO", + "Name": "California", + "SyncToken": "0", + "SpecialTaxType": "NONE", + "DisplayType": "ReadOnly", + "sparse": False, + "Active": True, + "MetaData": {"CreateTime": "2014-09-18T12:17:04-07:00", "LastUpdatedTime": "2014-09-18T12:17:04-07:00"}, + "Id": "2", + "Description": "Sales Tax", + }, + "create_new_auto_create_tax_groups_destination_attributes_subsequent_case": [ + { + "SyncToken": "0", + "domain": "QBO", + "TaxGroup": True, + "Name": "California", + "Taxable": True, + "PurchaseTaxRateList": {"TaxRateDetail": [{"TaxRateRef": {"value": "6", "name": "ON TAX PURCHASE"}, "TaxTypeApplicable": "TaxOnAmount", "TaxOrder": 0}]}, + "sparse": False, + "Active": True, + "Description": "California", + "MetaData": {"CreateTime": "2014-09-18T12:17:04-07:00", "LastUpdatedTime": "2014-09-18T12:17:04-07:00"}, + "Id": "2", + "SalesTaxRateList": {"TaxRateDetail": [{"TaxTypeApplicable": "TaxOnAmount", "TaxRateRef": {"name": "California", "value": "3"}, "TaxOrder": 0}]}, + }, + { + "SyncToken": "0", + "domain": "QBO", + "TaxGroup": True, + "Name": "Mumbai", + "Taxable": True, + "PurchaseTaxRateList": {"TaxRateDetail": [{"TaxRateRef": {"value": "6", "name": "ON TAX PURCHASE"}, "TaxTypeApplicable": "TaxOnAmount", "TaxOrder": 0}]}, + "sparse": False, + "Active": True, + "Description": "Mumbai", + "MetaData": {"CreateTime": "2014-09-18T12:17:04-07:00", "LastUpdatedTime": "2014-09-18T12:17:04-07:00"}, + "Id": "2", + "SalesTaxRateList": {"TaxRateDetail": [{"TaxTypeApplicable": "TaxOnAmount", "TaxRateRef": {"name": "Mumbai", "value": "3"}, "TaxOrder": 0}]}, + } + ], + "create_new_auto_create_tax_groups_destination_attributes_subsequent_case_get_by_id": { + "RateValue": 2, + "AgencyRef": {"value": "1"}, + "domain": "QBO", + "Name": "Mumbai", + "SyncToken": "0", + "SpecialTaxType": "NONE", + "DisplayType": "ReadOnly", + "sparse": False, + "Active": True, + "MetaData": {"CreateTime": "2014-09-18T12:17:04-07:00", "LastUpdatedTime": "2014-09-18T12:17:04-07:00"}, + "Id": "3", + "Description": "Sales Tax", + }, + "create_new_auto_create_tax_groups_expense_attributes_0":[ + { + 'count':3, + 'data':[ + { + 'code':None, + 'created_at':'2023-09-14T05:46:05.968869+00:00', + 'id':'tg151Bx7lDBP', + 'is_enabled':True, + 'name':'G10 Capital Acquisition', + 'org_id':'or5qYLrvnoF9', + 'percentage':0.1, + 'updated_at':'2023-09-14T05:46:05.968869+00:00' + }, + { + 'code':None, + 'created_at':'2023-09-14T05:46:05.968869+00:00', + 'id':'tg151Bx7lDBPlol1', + 'is_enabled':True, + 'name':'G199001201 Capital Acquisition', + 'org_id':'or5qYLrvnoF9', + 'percentage':0.2, + 'updated_at':'2023-09-14T05:46:05.968869+00:00' + }, + { + 'code':None, + 'created_at':'2023-09-14T05:46:05.968869+00:00', + 'id':'tg151Bx7lDBPlol2', + 'is_enabled':True, + 'name':'G199001202 Capital Acquisition', + 'org_id':'or5qYLrvnoF9', + 'percentage':0.2, + 'updated_at':'2023-09-14T05:46:05.968869+00:00' + }, + ], + 'offset':0 + } + ], + "create_new_auto_create_tax_groups_expense_attributes_1":[ + { + 'count':4, + 'data':[ + { + 'code':None, + 'created_at':'2023-09-14T05:46:05.968869+00:00', + 'id':'tg151Bx7lDBP', + 'is_enabled':True, + 'name':'G10 Capital Acquisition', + 'org_id':'or5qYLrvnoF9', + 'percentage':0.1, + 'updated_at':'2023-09-14T05:46:05.968869+00:00' + }, + { + 'code':None, + 'created_at':'2023-09-14T05:46:05.968869+00:00', + 'id':'tg151Bx7lDBPlol1', + 'is_enabled':True, + 'name':'G199001201 Capital Acquisition', + 'org_id':'or5qYLrvnoF9', + 'percentage':0.2, + 'updated_at':'2023-09-14T05:46:05.968869+00:00' + }, + { + 'code':None, + 'created_at':'2023-09-14T05:46:05.968869+00:00', + 'id':'tg151Bx7lDBPlol2', + 'is_enabled':True, + 'name':'G199001202 Capital Acquisition', + 'org_id':'or5qYLrvnoF9', + 'percentage':0.2, + 'updated_at':'2023-09-14T05:46:05.968869+00:00' + }, + { + 'code':None, + 'created_at':'2023-09-14T05:46:05.968869+00:00', + 'id':'tg151Bx7lDBPlol3', + 'is_enabled':True, + 'name':'California @2%', + 'org_id':'or5qYLrvnoF9', + 'percentage':0.2, + 'updated_at':'2023-09-14T05:46:05.968869+00:00' + }, + ], + 'offset':0 + } + ], + "create_new_auto_create_tax_groups_expense_attributes_2":[ + { + 'count':5, + 'data':[ + { + 'code':None, + 'created_at':'2023-09-14T05:46:05.968869+00:00', + 'id':'tg151Bx7lDBP', + 'is_enabled':True, + 'name':'G10 Capital Acquisition', + 'org_id':'or5qYLrvnoF9', + 'percentage':0.1, + 'updated_at':'2023-09-14T05:46:05.968869+00:00' + }, + { + 'code':None, + 'created_at':'2023-09-14T05:46:05.968869+00:00', + 'id':'tg151Bx7lDBPlol1', + 'is_enabled':True, + 'name':'G199001201 Capital Acquisition', + 'org_id':'or5qYLrvnoF9', + 'percentage':0.2, + 'updated_at':'2023-09-14T05:46:05.968869+00:00' + }, + { + 'code':None, + 'created_at':'2023-09-14T05:46:05.968869+00:00', + 'id':'tg151Bx7lDBPlol2', + 'is_enabled':True, + 'name':'G199001202 Capital Acquisition', + 'org_id':'or5qYLrvnoF9', + 'percentage':0.2, + 'updated_at':'2023-09-14T05:46:05.968869+00:00' + }, + { + 'code':None, + 'created_at':'2023-09-14T05:46:05.968869+00:00', + 'id':'tg151Bx7lDBPlol3', + 'is_enabled':True, + 'name':'California @2%', + 'org_id':'or5qYLrvnoF9', + 'percentage':0.2, + 'updated_at':'2023-09-14T05:46:05.968869+00:00' + }, + { + 'code':None, + 'created_at':'2023-09-14T05:46:05.968869+00:00', + 'id':'tg151Bx7lDBPlol3', + 'is_enabled':True, + 'name':'Mumbai @2%', + 'org_id':'or5qYLrvnoF9', + 'percentage':0.2, + 'updated_at':'2023-09-14T05:46:05.968869+00:00' + }, + ], + 'offset':0 + } + ], + "create_fyle_tax_groups_payload_create_new_case": [{'name': '0.0% ECG @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': '0.0% ECS @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': '0.0% Z @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': '12.5% TR @12.5%', 'is_enabled': True, 'percentage': 0.12}, {'name': '20.0% ECG @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': '20.0% ECS @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': '20.0% RC @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': '20.0% RC CIS @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': '20.0% RC MPCCs @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': '20.0% RC SG @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': '20.0% S @20%', 'is_enabled': True, 'percentage': 0.2}, {'name': '5.0% R @5%', 'is_enabled': True, 'percentage': 0.05}, {'name': '5.0% RC CIS @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': 'Exempt @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': 'Fyle Tax @10%', 'is_enabled': True, 'percentage': 0.1}, {'name': 'Fyle UK Purchase Tax @20%', 'is_enabled': True, 'percentage': 0.2}, {'name': 'GST @21%', 'is_enabled': True, 'percentage': 0.21}, {'name': 'KSK @10%', 'is_enabled': True, 'percentage': 0.1}, {'name': 'KSK Tax @10%', 'is_enabled': True, 'percentage': 0.1}, {'name': 'No VAT @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': 'Platform Tax @2%', 'is_enabled': True, 'percentage': 0.02}, {'name': 'PVA Import 0.0% @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': 'PVA Import 20.0% @0%', 'is_enabled': True, 'percentage': 0.0}, {'name': 'Staging Tax @10%', 'is_enabled': True, 'percentage': 0.1}] +} + +merchants_data = { + "create_new_auto_create_merchants_destination_attributes": [ + { + "PrimaryEmailAddr": {"Address": "Books@Intuit.com"}, + "Vendor1099": False, + "domain": "QBO", + "GivenName": "Bessie", + "DisplayName": "Books by Bessie", + 'CurrencyRef': {'value': 'USD', 'name': 'United States Dollar'}, + "BillAddr": {"City": "Palo Alto", "Line1": "15 Main St.", "PostalCode": "94303", "Lat": "37.445013", "Long": "-122.1391443", "CountrySubDivisionCode": "CA", "Id": "31"}, + "SyncToken": "0", + "PrintOnCheckName": "Books by Bessie", + "FamilyName": "Williams", + "PrimaryPhone": {"FreeFormNumber": "(650) 555-7745"}, + "AcctNum": "1345", + "CompanyName": "Books by Bessie", + "WebAddr": {"URI": "http://www.booksbybessie.co"}, + "sparse": False, + "Active": True, + "Balance": 0, + "Id": "30", + "MetaData": {"CreateTime": "2014-09-12T10:07:56-07:00", "LastUpdatedTime": "2014-09-17T11:13:46-07:00"}, + }, + { + "PrimaryEmailAddr": {"Address": "Books@Intuit.com"}, + "Vendor1099": False, + "domain": "QBO", + "GivenName": "jessie", + "DisplayName": "Books by jessie", + 'CurrencyRef': {'value': 'USD', 'name': 'United States Dollar'}, + "BillAddr": {"City": "Palo Alto", "Line1": "15 Main St.", "PostalCode": "94303", "Lat": "37.445013", "Long": "-122.1391443", "CountrySubDivisionCode": "CA", "Id": "31"}, + "SyncToken": "0", + "PrintOnCheckName": "Books by jessie", + "FamilyName": "Williams", + "PrimaryPhone": {"FreeFormNumber": "(650) 555-7745"}, + "AcctNum": "1345", + "CompanyName": "Books by jessie", + "WebAddr": {"URI": "http://www.booksbyjessie.co"}, + "sparse": False, + "Active": True, + "Balance": 0, + "Id": "31", + "MetaData": {"CreateTime": "2014-09-12T10:07:56-07:00", "LastUpdatedTime": "2014-09-17T11:13:46-07:00"}, + } + ], + "create_new_auto_create_merchants_destination_attributes_subsequent_run": [ + { + "PrimaryEmailAddr": {"Address": "Books@Intuit.com"}, + "Vendor1099": False, + "domain": "QBO", + "GivenName": "Bessie", + "DisplayName": "Books by Bessie", + 'CurrencyRef': {'value': 'USD', 'name': 'United States Dollar'}, + "BillAddr": {"City": "Palo Alto", "Line1": "15 Main St.", "PostalCode": "94303", "Lat": "37.445013", "Long": "-122.1391443", "CountrySubDivisionCode": "CA", "Id": "31"}, + "SyncToken": "0", + "PrintOnCheckName": "Books by Bessie", + "FamilyName": "Williams", + "PrimaryPhone": {"FreeFormNumber": "(650) 555-7745"}, + "AcctNum": "1345", + "CompanyName": "Books by Bessie", + "WebAddr": {"URI": "http://www.booksbybessie.co"}, + "sparse": False, + "Active": True, + "Balance": 0, + "Id": "30", + "MetaData": {"CreateTime": "2014-09-12T10:07:56-07:00", "LastUpdatedTime": "2014-09-17T11:13:46-07:00"}, + }, + { + "PrimaryEmailAddr": {"Address": "Books@Intuit.com"}, + "Vendor1099": False, + "domain": "QBO", + "GivenName": "jessie", + "DisplayName": "Books by jessie", + 'CurrencyRef': {'value': 'USD', 'name': 'United States Dollar'}, + "BillAddr": {"City": "Palo Alto", "Line1": "15 Main St.", "PostalCode": "94303", "Lat": "37.445013", "Long": "-122.1391443", "CountrySubDivisionCode": "CA", "Id": "31"}, + "SyncToken": "0", + "PrintOnCheckName": "Books by jessie", + "FamilyName": "Williams", + "PrimaryPhone": {"FreeFormNumber": "(650) 555-7745"}, + "AcctNum": "1345", + "CompanyName": "Books by jessie", + "WebAddr": {"URI": "http://www.booksbyjessie.co"}, + "sparse": False, + "Active": True, + "Balance": 0, + "Id": "31", + "MetaData": {"CreateTime": "2014-09-12T10:07:56-07:00", "LastUpdatedTime": "2014-09-17T11:13:46-07:00"}, + }, + { + "PrimaryEmailAddr": {"Address": "Books@Intuit.com"}, + "Vendor1099": False, + "domain": "QBO", + "GivenName": "lessies", + "DisplayName": "Books by lessies", + 'CurrencyRef': {'value': 'USD', 'name': 'United States Dollar'}, + "BillAddr": {"City": "Palo Alto", "Line1": "15 Main St.", "PostalCode": "94303", "Lat": "37.445013", "Long": "-122.1391443", "CountrySubDivisionCode": "CA", "Id": "31"}, + "SyncToken": "0", + "PrintOnCheckName": "Books by lessies", + "FamilyName": "Williams", + "PrimaryPhone": {"FreeFormNumber": "(650) 555-7745"}, + "AcctNum": "1345", + "CompanyName": "Books by lessies", + "WebAddr": {"URI": "http://www.booksbylessies.co"}, + "sparse": False, + "Active": True, + "Balance": 0, + "Id": "32", + "MetaData": {"CreateTime": "2014-09-12T10:07:56-07:00", "LastUpdatedTime": "2014-09-17T11:13:46-07:00"}, + } + ], + 'create_new_auto_create_merchants_expense_attributes_0': [ + { + 'count':1, + 'data':[ + { + 'category_ids':[ + 259385, + 259386, + 259387, + 259388, + 259389, + 273385 + ], + 'code':None, + 'column_name':'merchant', + 'created_at':'2023-06-01T04:46:25.644307+00:00', + 'default_value':'', + 'field_name':'Merchant', + 'id':225221, + 'is_custom':False, + 'is_enabled':True, + 'is_mandatory':False, + 'options':[ + 'ADP', + 'Goner', + 'Keventers', + 'Whirpool' + ], + 'org_id':'or5qYLrvnoF9', + 'parent_field_id':None, + 'placeholder':'E.g. Uber', + 'seq':1, + 'type':'SELECT', + 'updated_at':'2023-10-23T12:20:00.035384+00:00' + } + ], + 'offset':0 + } + ], + 'create_new_auto_create_merchants_expense_attributes_1': [ + { + 'count':1, + 'data':[ + { + 'category_ids':[ + 259385, + 259386, + 259387, + 259388, + 259389, + 273385 + ], + 'code':None, + 'column_name':'merchant', + 'created_at':'2023-06-01T04:46:25.644307+00:00', + 'default_value':'', + 'field_name':'Merchant', + 'id':225221, + 'is_custom':False, + 'is_enabled':True, + 'is_mandatory':False, + 'options':[ + 'ADP', + 'Goner', + 'Keventers', + 'Whirpool', + 'Books by jessie', + 'Books by Bessie' + ], + 'org_id':'or5qYLrvnoF9', + 'parent_field_id':None, + 'placeholder':'E.g. Uber', + 'seq':1, + 'type':'SELECT', + 'updated_at':'2023-10-23T12:20:00.035384+00:00' + } + ], + 'offset':0 + } + ], + 'create_new_auto_create_merchants_expense_attributes_2': [ + { + 'count':1, + 'data':[ + { + 'category_ids':[ + 259385, + 259386, + 259387, + 259388, + 259389, + 273385 + ], + 'code':None, + 'column_name':'merchant', + 'created_at':'2023-06-01T04:46:25.644307+00:00', + 'default_value':'', + 'field_name':'Merchant', + 'id':225221, + 'is_custom':False, + 'is_enabled':True, + 'is_mandatory':False, + 'options':[ + 'ADP', + 'Goner', + 'Keventers', + 'Whirpool', + 'Books by jessie', + 'Books by Bessie', + 'Books by lessies' + ], + 'org_id':'or5qYLrvnoF9', + 'parent_field_id':None, + 'placeholder':'E.g. Uber', + 'seq':1, + 'type':'SELECT', + 'updated_at':'2023-10-23T12:20:00.035384+00:00' + } + ], + 'offset':0 + } + ], + "create_fyle_merchants_payload_create_new_case": ['Andrew Haberbosch', 'Town Electric & Gas Service', 'Vendor KS', "Garcia's Event Space", 'Gina Han', 'Arun', 'Ashwin', 'Bank of AnyCity', 'Basket Case', 'Brijesh Jain', 'Brittney Hughes', 'Burc Gunes', 'Cass Hayden', 'Celeste Hunter', 'City Water Co', 'Colleen Grist', 'Fyle For QBO Paymrnt Sync', "Hall's Promo Items", 'Heather Gottas', 'Import Setting vendor', 'Jacque Hudspeth', 'James Taylor', 'Jane Horton', 'Jennifer Hargreaves', 'Julie Hickey', 'Kimberly Howell', 'Kristina Gibson', 'Kristina Holmgren', 'Kyle Kilat', 'Mark Howard', 'Matt Damon', 'Mauro Giansiracusa', 'Michelle Long', 'Mindy Khoo', 'Monica Haslip', 'Olivier Helleboid', 'Organization of Outstanding Event Planners', 'QBO V2 Supplier', 'Rajeswari Jayaraman', 'Sanjeev Kak', 'Sravan KSK', 'Sravan Kumar', 'Sukanya Kanogart', 'Tom Hurlbutt', 'Venue Rental'] +} diff --git a/tests/test_fyle_integrations_imports/test_modules/test_merchants.py b/tests/test_fyle_integrations_imports/test_modules/test_merchants.py new file mode 100644 index 00000000..e5059dc2 --- /dev/null +++ b/tests/test_fyle_integrations_imports/test_modules/test_merchants.py @@ -0,0 +1,172 @@ +from unittest import mock +from fyle_accounting_mappings.models import ( + DestinationAttribute, + ExpenseAttribute, + Mapping, +) +from apps.quickbooks_online.utils import QBOConnector +from apps.workspaces.models import QBOCredential, FyleCredential, Workspace +from fyle_integrations_platform_connector import PlatformConnector +from fyle_integrations_imports.modules.merchants import Merchant +from tests.test_fyle_integrations_imports.test_modules.fixtures import merchants_data + + +def test_sync_destination_attributes(mocker, db): + workspace_id = 5 + + mocker.patch( + 'qbosdk.apis.Vendors.get', + return_value=merchants_data['create_new_auto_create_merchants_destination_attributes'] + ) + + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + + DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='VENDOR').delete() + + destination_attributes_count = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='VENDOR').count() + assert destination_attributes_count == 0 + + merchant = Merchant(workspace_id, 'VENDOR', None, qbo_connection, ['vendors']) + merchant.sync_destination_attributes() + + destination_attributes_count = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='VENDOR').count() + assert destination_attributes_count == 2 + + +def test_sync_expense_atrributes(mocker, db): + workspace_id = 5 + fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) + fyle_credentials.workspace.fyle_org_id = 'or5qYLrvnoF9' + fyle_credentials.workspace.save() + platform = PlatformConnector(fyle_credentials=fyle_credentials) + + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='MERCHANT').delete() + + mocker.patch( + 'fyle.platform.apis.v1beta.admin.expense_fields.list_all', + return_value=[] + ) + + merchant_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='MERCHANT').count() + assert merchant_count == 0 + + merchant = Merchant(workspace_id, 'VENDOR', None, qbo_connection, ['vendors']) + merchant.sync_expense_attributes(platform) + + merchant_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='MERCHANT').count() + assert merchant_count == 0 + + mocker.patch( + 'fyle.platform.apis.v1beta.admin.expense_fields.list_all', + return_value=merchants_data['create_new_auto_create_merchants_expense_attributes_0'] + ) + + merchant = Merchant(workspace_id, 'VENDOR', None, qbo_connection, ['vendors']) + merchant.sync_expense_attributes(platform) + + merchant_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='MERCHANT').count() + assert merchant_count == 4 + + +def test_auto_create_destination_attributes(mocker, db): + workspace_id = 5 + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + merchant = Merchant(workspace_id, 'VENDOR', None, qbo_connection, ['vendors']) + merchant.sync_after = None + + Workspace.objects.filter(id=workspace_id).update(fyle_org_id='or5qYLrvnoF9') + + # delete all destination attributes, expense attributes and mappings + DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='VENDOR').delete() + ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='MERCHANT').delete() + + # create new case for merchants import + with mock.patch('fyle.platform.apis.v1beta.admin.expense_fields.list_all') as mock_call: + mocker.patch( + 'fyle_integrations_platform_connector.apis.Merchants.post', + return_value=[] + ) + mocker.patch( + 'qbosdk.apis.Vendors.get', + return_value=merchants_data['create_new_auto_create_merchants_destination_attributes'] + ) + mock_call.side_effect = [ + merchants_data['create_new_auto_create_merchants_expense_attributes_0'], + merchants_data['create_new_auto_create_merchants_expense_attributes_1'] + ] + + expense_attributes_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'MERCHANT').count() + + assert expense_attributes_count == 0 + + mappings_count = Mapping.objects.filter(workspace_id=workspace_id, source_type='MERCHANT', destination_type='VENDOR').count() + + assert mappings_count == 0 + + merchant.trigger_import() + + expense_attributes_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'MERCHANT').count() + + assert expense_attributes_count == 6 + + # we dont create mappings for merchants + mappings_count = Mapping.objects.filter(workspace_id=workspace_id, source_type='MERCHANT', destination_type='VENDOR').count() + + assert mappings_count == 0 + + # create subsequent case for merchants import + with mock.patch('fyle.platform.apis.v1beta.admin.expense_fields.list_all') as mock_call: + mocker.patch( + 'fyle_integrations_platform_connector.apis.Merchants.post', + return_value=[] + ) + mocker.patch( + 'qbosdk.apis.Vendors.get', + return_value=merchants_data['create_new_auto_create_merchants_destination_attributes_subsequent_run'] + ) + mock_call.side_effect = [ + merchants_data['create_new_auto_create_merchants_expense_attributes_1'], + merchants_data['create_new_auto_create_merchants_expense_attributes_2'] + ] + + expense_attributes_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'MERCHANT').count() + + assert expense_attributes_count == 6 + + mappings_count = Mapping.objects.filter(workspace_id=workspace_id, source_type='MERCHANT', destination_type='VENDOR').count() + + assert mappings_count == 0 + + merchant.trigger_import() + + expense_attributes_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'MERCHANT').count() + + assert expense_attributes_count == 7 + + # we dont create mappings for merchants + mappings_count = Mapping.objects.filter(workspace_id=workspace_id, source_type='MERCHANT', destination_type='VENDOR').count() + + assert mappings_count == 0 + + +def test_construct_fyle_payload(db): + workspace_id = 5 + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + merchant = Merchant(workspace_id, 'VENDOR', None, qbo_connection, ['vendors']) + merchant.sync_after = None + + # create new case + paginated_destination_attributes = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='VENDOR') + existing_fyle_attributes_map = {} + + fyle_payload = merchant.construct_fyle_payload( + paginated_destination_attributes, + existing_fyle_attributes_map, + ) + + assert fyle_payload == merchants_data['create_fyle_merchants_payload_create_new_case'] diff --git a/tests/test_fyle_integrations_imports/test_modules/test_tax_groups.py b/tests/test_fyle_integrations_imports/test_modules/test_tax_groups.py new file mode 100644 index 00000000..bebbe53b --- /dev/null +++ b/tests/test_fyle_integrations_imports/test_modules/test_tax_groups.py @@ -0,0 +1,195 @@ +from unittest import mock +from fyle_accounting_mappings.models import ( + DestinationAttribute, + ExpenseAttribute, + Mapping, +) +from apps.quickbooks_online.utils import QBOConnector +from apps.workspaces.models import QBOCredential, FyleCredential, Workspace +from fyle_integrations_platform_connector import PlatformConnector +from fyle_integrations_imports.modules.tax_groups import TaxGroup +from tests.test_fyle_integrations_imports.test_modules.fixtures import tax_groups_data + + +def test_sync_destination_attributes(mocker, db): + workspace_id = 5 + mocker.patch( + 'qbosdk.apis.TaxCodes.get', + return_value=tax_groups_data['create_new_auto_create_tax_groups_destination_attributes'] + ) + mocker.patch( + 'qbosdk.apis.TaxRates.get_by_id', + return_value=tax_groups_data['create_new_auto_create_tax_groups_destination_attributes_get_by_id'] + ) + + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + + Mapping.objects.filter(workspace_id=workspace_id, source_type='TAX_GROUP').delete() + DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_CODE').delete() + + destination_attributes_count = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_CODE').count() + assert destination_attributes_count == 0 + + tax_group = TaxGroup(workspace_id, 'TAX_CODE', None, qbo_connection, ['tax_codes']) + tax_group.sync_after = None + tax_group.sync_destination_attributes() + + destination_attributes_count = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_CODE').count() + assert destination_attributes_count == 1 + + +def test_sync_expense_atrributes(mocker, db): + workspace_id = 5 + fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) + fyle_credentials.workspace.fyle_org_id = 'or5qYLrvnoF9' + fyle_credentials.workspace.save() + platform = PlatformConnector(fyle_credentials=fyle_credentials) + + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + + Mapping.objects.filter(workspace_id=workspace_id, source_type='TAX_GROUP').delete() + Mapping.objects.filter(workspace_id=workspace_id, destination_type='TAX_CODE').delete() + DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_CODE').delete() + ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_GROUP').delete() + + tax_group_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_GROUP').count() + assert tax_group_count == 0 + + mocker.patch( + 'fyle.platform.apis.v1beta.admin.TaxGroups.list_all', + return_value=[] + ) + + tax_group = TaxGroup(workspace_id, 'TAX_CODE', None, qbo_connection, ['tax_codes']) + tax_group.sync_after = None + tax_group.sync_expense_attributes(platform) + + tax_group_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_GROUP').count() + assert tax_group_count == 0 + + mocker.patch( + 'fyle.platform.apis.v1beta.admin.TaxGroups.list_all', + return_value=tax_groups_data['create_new_auto_create_tax_groups_expense_attributes_1'] + ) + + tax_group.sync_expense_attributes(platform) + + tax_group_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_GROUP').count() + assert tax_group_count == 4 + + +def test_auto_create_destination_attributes(mocker, db): + workspace_id = 5 + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + tax_group = TaxGroup(workspace_id, 'TAX_CODE', None, qbo_connection, ['tax_codes']) + tax_group.sync_after = None + + Workspace.objects.filter(id=workspace_id).update(fyle_org_id='or5qYLrvnoF9') + + # delete all destination attributes, expense attributes and mappings + Mapping.objects.filter(workspace_id=workspace_id, source_type='TAX_GROUP').delete() + Mapping.objects.filter(workspace_id=workspace_id, destination_type='TAX_CODE').delete() + DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_CODE').delete() + ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_GROUP').delete() + + # create new case for tax-groups import + with mock.patch('fyle.platform.apis.v1beta.admin.TaxGroups.list_all') as mock_call: + mocker.patch( + 'fyle_integrations_platform_connector.apis.TaxGroups.post_bulk', + return_value=[] + ) + mocker.patch( + 'qbosdk.apis.TaxCodes.get', + return_value=tax_groups_data['create_new_auto_create_tax_groups_destination_attributes'] + ) + mocker.patch( + 'qbosdk.apis.TaxRates.get_by_id', + return_value=tax_groups_data['create_new_auto_create_tax_groups_destination_attributes_get_by_id'] + ) + mock_call.side_effect = [ + tax_groups_data['create_new_auto_create_tax_groups_expense_attributes_0'], + tax_groups_data['create_new_auto_create_tax_groups_expense_attributes_1'] + ] + + expense_attributes_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'TAX_GROUP').count() + + assert expense_attributes_count == 0 + + mappings_count = Mapping.objects.filter(workspace_id=workspace_id, source_type='TAX_GROUP', destination_type='TAX_CODE').count() + + assert mappings_count == 0 + + tax_group.trigger_import() + + expense_attributes_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'TAX_GROUP').count() + + assert expense_attributes_count == 4 + + mappings_count = Mapping.objects.filter(workspace_id=workspace_id, source_type='TAX_GROUP', destination_type='TAX_CODE').count() + + assert mappings_count == 1 + + # create subsequen case for tax-groups import + with mock.patch('fyle.platform.apis.v1beta.admin.TaxGroups.list_all') as mock_call: + mocker.patch( + 'fyle_integrations_platform_connector.apis.TaxGroups.post_bulk', + return_value=[] + ) + mocker.patch( + 'qbosdk.apis.TaxCodes.get', + return_value=tax_groups_data['create_new_auto_create_tax_groups_destination_attributes_subsequent_case'] + ) + mocker.patch( + 'qbosdk.apis.TaxRates.get_by_id', + return_value=tax_groups_data['create_new_auto_create_tax_groups_destination_attributes_get_by_id'] + ) + mocker.patch( + 'qbosdk.apis.TaxRates.get_by_id', + return_value=tax_groups_data['create_new_auto_create_tax_groups_destination_attributes_subsequent_case_get_by_id'] + ) + mock_call.side_effect = [ + tax_groups_data['create_new_auto_create_tax_groups_expense_attributes_1'], + tax_groups_data['create_new_auto_create_tax_groups_expense_attributes_2'] + ] + + expense_attributes_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'TAX_GROUP').count() + + assert expense_attributes_count == 4 + + mappings_count = Mapping.objects.filter(workspace_id=workspace_id, source_type='TAX_GROUP', destination_type='TAX_CODE').count() + + assert mappings_count == 1 + + tax_group.trigger_import() + + expense_attributes_count = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type = 'TAX_GROUP').count() + + assert expense_attributes_count == 5 + + mappings_count = Mapping.objects.filter(workspace_id=workspace_id, source_type='TAX_GROUP', destination_type='TAX_CODE').count() + + assert mappings_count == 2 + + +def test_construct_fyle_payload(db): + workspace_id = 5 + qbo_credentials = QBOCredential.get_active_qbo_credentials(workspace_id) + qbo_connection = QBOConnector(credentials_object=qbo_credentials, workspace_id=workspace_id) + tax_group = TaxGroup(workspace_id, 'TAX_CODE', None, qbo_connection, ['tax_codes']) + tax_group.sync_after = None + + # create new case + paginated_destination_attributes = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_CODE') + existing_fyle_attributes_map = {} + + fyle_payload = tax_group.construct_fyle_payload( + paginated_destination_attributes, + existing_fyle_attributes_map, + ) + + print(fyle_payload) + + assert fyle_payload == tax_groups_data['create_fyle_tax_groups_payload_create_new_case'] diff --git a/tests/test_mappings/test_tasks.py b/tests/test_mappings/test_tasks.py index 5037e802..bf4b00ee 100644 --- a/tests/test_mappings/test_tasks.py +++ b/tests/test_mappings/test_tasks.py @@ -1,94 +1,21 @@ -from unittest import mock - from django_q.models import Schedule -from fyle.platform.exceptions import InvalidTokenError as FyleInvalidTokenError from fyle_accounting_mappings.models import ( - DestinationAttribute, EmployeeMapping, - ExpenseAttribute, - Mapping, - MappingSetting, ) -from fyle_integrations_platform_connector import PlatformConnector -from qbosdk.exceptions import WrongParamsError from apps.mappings.queues import ( schedule_auto_map_ccc_employees, - schedule_auto_map_employees, - schedule_tax_groups_creation, + schedule_auto_map_employees ) from apps.mappings.tasks import ( - Chain, async_auto_map_ccc_account, async_auto_map_employees, - auto_create_tax_codes_mappings, - auto_create_vendors_as_merchants, - auto_import_and_map_fyle_fields, auto_map_ccc_employees, auto_map_employees, - post_merchants, - remove_duplicates, resolve_expense_attribute_errors, ) from apps.tasks.models import Error -from apps.workspaces.models import FyleCredential, QBOCredential, WorkspaceGeneralSettings -from tests.test_mappings.fixtures import data - - -def test_auto_create_tax_codes_mappings(db, mocker): - workspace_id = 5 - mocker.patch('qbosdk.apis.TaxCodes.get', return_value=[]) - mocker.patch('fyle_integrations_platform_connector.apis.TaxGroups.post_bulk', return_value=[]) - mocker.patch('fyle_integrations_platform_connector.apis.TaxGroups.sync', return_value=[]) - - tax_groups = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_CODE').count() - mappings = Mapping.objects.filter(workspace_id=workspace_id, destination_type='TAX_CODE').count() - - assert tax_groups == 24 - assert mappings == 23 - auto_create_tax_codes_mappings(workspace_id=workspace_id) - - tax_groups = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='TAX_CODE').count() - mappings = Mapping.objects.filter(workspace_id=workspace_id, destination_type='TAX_CODE').count() - assert mappings == 23 - - with mock.patch('fyle_integrations_platform_connector.apis.TaxGroups.sync') as mock_call: - mock_call.side_effect = WrongParamsError(msg='invalid params', response='invalid params') - auto_create_tax_codes_mappings(workspace_id=workspace_id) - - with mock.patch('fyle_integrations_platform_connector.apis.TaxGroups.sync') as mock_call: - mock_call.side_effect = FyleInvalidTokenError(msg='Invalid Token for fyle', response='Invalid Token for fyle') - auto_create_tax_codes_mappings(workspace_id=workspace_id) - - fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) - fyle_credentials.delete() - - response = auto_create_tax_codes_mappings(workspace_id) - assert response == None - - -def test_schedule_tax_groups_creation(db): - workspace_id = 5 - schedule_tax_groups_creation(import_tax_codes=True, workspace_id=workspace_id) - - schedule = Schedule.objects.filter(func='apps.mappings.tasks.auto_create_tax_codes_mappings', args='{}'.format(workspace_id)).first() - - assert schedule.func == 'apps.mappings.tasks.auto_create_tax_codes_mappings' - - schedule_tax_groups_creation(import_tax_codes=False, workspace_id=workspace_id) - - schedule = Schedule.objects.filter(func='apps.mappings.tasks.auto_create_tax_codes_mappings', args='{}'.format(workspace_id)).first() - - assert schedule == None - - -def test_remove_duplicates(db): - - attributes = DestinationAttribute.objects.filter(attribute_type='EMPLOYEE') - assert len(attributes) == 19 - - attributes = remove_duplicates(attributes) - assert len(attributes) == 12 +from apps.workspaces.models import QBOCredential, WorkspaceGeneralSettings def test_auto_map_employees(db): @@ -178,54 +105,6 @@ def test_schedule_auto_map_ccc_employees(db): assert schedule == None -def test_post_merchants(db, mocker): - mocker.patch('fyle_integrations_platform_connector.apis.Merchants.get', return_value=data['get_merchants']) - mocker.patch('fyle_integrations_platform_connector.apis.Merchants.post', return_value=[]) - mocker.patch('fyle.platform.apis.v1beta.admin.expense_fields', return_value=data['get_merchants']) - workspace_id = 5 - fyle_credentials = FyleCredential.objects.all() - fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) - fyle_connection = PlatformConnector(fyle_credentials) - - post_merchants(fyle_connection, workspace_id) - - expense_attribute = ExpenseAttribute.objects.filter(attribute_type='MERCHANT', workspace_id=workspace_id).count() - assert expense_attribute == 44 - - -def test_auto_create_vendors_as_merchants(db, mocker): - workspace_id = 1 - mocker.patch('fyle_integrations_platform_connector.apis.Merchants.sync', return_value=[]) - mocker.patch('fyle_integrations_platform_connector.apis.Merchants.post', return_value=[]) - mocker.patch('qbosdk.apis.Vendors.get', return_value=[]) - - vendors = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='VENDOR').count() - expense_attribute = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='MERCHANT').count() - assert vendors == 29 - assert expense_attribute == 0 - - auto_create_vendors_as_merchants(workspace_id=workspace_id) - - vendors = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='VENDOR').count() - expense_attribute = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='MERCHANT').count() - assert vendors == 29 - assert expense_attribute == 0 - - with mock.patch('fyle_integrations_platform_connector.apis.Merchants.sync') as mock_call: - mock_call.side_effect = WrongParamsError(msg='invalid params', response='invalid params') - auto_create_vendors_as_merchants(workspace_id=workspace_id) - - mock_call.side_effect = FyleInvalidTokenError(msg='Invalid Token for fyle', response='Invalid Token for fyle') - auto_create_vendors_as_merchants(workspace_id=workspace_id) - - fyle_credentials = FyleCredential.objects.get(workspace_id=1) - fyle_credentials.delete() - - response = auto_create_vendors_as_merchants(workspace_id=1) - - assert response == None - - def test_resolve_expense_attribute_errors(db): workspace_id = 3 errors = Error.objects.filter(workspace_id=workspace_id, type='EMPLOYEE_MAPPING', expense_attribute_id=5327, is_resolved=False).count() @@ -235,28 +114,3 @@ def test_resolve_expense_attribute_errors(db): errors = Error.objects.filter(workspace_id=workspace_id, type='EMPLOYEE_MAPPING', expense_attribute_id=5327, is_resolved=False).count() assert errors == 0 - - -def test_auto_import_and_map_fyle_field(db, mocker): - workspace_id = 3 - mocker.patch.object(WorkspaceGeneralSettings.objects, 'get', return_value=WorkspaceGeneralSettings(workspace_id=workspace_id)) - mocker.patch.object(MappingSetting.objects, 'filter', return_value=MappingSetting.objects.none()) - - chain_mock = mocker.Mock(Chain) - mocker.patch.object(Chain, 'append', return_value=chain_mock) - mocker.patch.object(chain_mock, 'length', return_value=0) - - vendors = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='VENDOR').count() - expense_attribute = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='MERCHANT').count() - assert vendors == 29 - assert expense_attribute == 89 - - auto_import_and_map_fyle_fields(workspace_id=workspace_id) - - vendors = DestinationAttribute.objects.filter(workspace_id=workspace_id, attribute_type='VENDOR').count() - expense_attribute = ExpenseAttribute.objects.filter(workspace_id=workspace_id, attribute_type='MERCHANT').count() - assert vendors == 29 - assert expense_attribute == 89 - - mocker.patch.object(MappingSetting.objects, 'filter', return_value=MappingSetting.objects.all()[:1]) - mocker.patch.object(Chain, 'run') From 74d0f9864f06480dc8a12304c9748afc0d9c88fe Mon Sep 17 00:00:00 2001 From: labhvam5 Date: Tue, 26 Dec 2023 12:24:45 +0530 Subject: [PATCH 4/4] changing sub module to master --- fyle_integrations_imports | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fyle_integrations_imports b/fyle_integrations_imports index b78722ad..0eaef5d4 160000 --- a/fyle_integrations_imports +++ b/fyle_integrations_imports @@ -1 +1 @@ -Subproject commit b78722ad1ec78bff96a0624fbfe20b68b4a562af +Subproject commit 0eaef5d4f961c8c7ba2d582e82eae841864f3959