From 31a423950af9a60a1f889fdcdefc0ae6ea966f46 Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari Date: Thu, 5 Sep 2024 15:34:00 +0530 Subject: [PATCH 01/12] fix disable attribute --- apps/mappings/imports/modules/categories.py | 15 ++++-- apps/mappings/imports/modules/cost_centers.py | 15 ++++-- apps/mappings/imports/modules/merchants.py | 11 ++++- apps/mappings/imports/modules/projects.py | 20 ++++++-- apps/sage300/utils.py | 46 ++++++++++++++++--- requirements.txt | 2 +- .../test_modules/test_categories.py | 6 +-- .../test_modules/test_cost_centers.py | 6 +-- .../test_modules/test_merchants.py | 6 +-- tests/test_sage300/test_helpers.py | 10 ++-- 10 files changed, 104 insertions(+), 33 deletions(-) diff --git a/apps/mappings/imports/modules/categories.py b/apps/mappings/imports/modules/categories.py index 6bf27ec..84e5612 100644 --- a/apps/mappings/imports/modules/categories.py +++ b/apps/mappings/imports/modules/categories.py @@ -90,7 +90,7 @@ def create_mappings(self): ) -def disable_categories(workspace_id: int, categories_to_disable: Dict, *args, **kwargs): +def disable_categories(workspace_id: int, categories_to_disable: Dict, is_import_to_fyle_enabled: bool = False, *args, **kwargs): """ categories_to_disable object format: { @@ -102,6 +102,10 @@ def disable_categories(workspace_id: int, categories_to_disable: Dict, *args, ** } } """ + if not is_import_to_fyle_enabled or len(categories_to_disable) == 0: + logger.info("Skipping disabling categories in Fyle | WORKSPACE_ID: %s", workspace_id) + return + fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) platform = PlatformConnector(fyle_credentials=fyle_credentials) @@ -109,6 +113,11 @@ def disable_categories(workspace_id: int, categories_to_disable: Dict, *args, ** category_values = [] for category_map in categories_to_disable.values(): + if not use_code_in_naming and category_map['value'] == category_map['updated_value']: + continue + elif use_code_in_naming and (category_map['value'] == category_map['updated_value'] and category_map['code'] == category_map['update_code']): + continue + category_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=category_map['value'], code=category_map['code']) category_values.append(category_name) @@ -121,9 +130,9 @@ def disable_categories(workspace_id: int, categories_to_disable: Dict, *args, ** # Expense attribute value map is as follows: {old_category_name: destination_id} expense_attribute_value_map = {} - for k, v in categories_to_disable.items(): + for destination_id, v in categories_to_disable.items(): category_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=v['value'], code=v['code']) - expense_attribute_value_map[category_name] = k + expense_attribute_value_map[category_name] = destination_id expense_attributes = ExpenseAttribute.objects.filter(**filters) diff --git a/apps/mappings/imports/modules/cost_centers.py b/apps/mappings/imports/modules/cost_centers.py index 6804d72..581117f 100644 --- a/apps/mappings/imports/modules/cost_centers.py +++ b/apps/mappings/imports/modules/cost_centers.py @@ -65,7 +65,7 @@ def construct_fyle_payload( return payload -def disable_cost_centers(workspace_id: int, cost_centers_to_disable: Dict, *args, **kwargs): +def disable_cost_centers(workspace_id: int, cost_centers_to_disable: Dict, is_import_to_fyle_enabled: bool = False, *args, **kwargs): """ cost_centers_to_disable object format: { @@ -77,6 +77,10 @@ def disable_cost_centers(workspace_id: int, cost_centers_to_disable: Dict, *args } } """ + if not is_import_to_fyle_enabled or len(cost_centers_to_disable) == 0: + logger.info("Skipping disabling cost centers in Fyle | WORKSPACE_ID: %s", workspace_id) + return + destination_type = MappingSetting.objects.get(workspace_id=workspace_id, source_field='COST_CENTER').destination_field use_code_in_naming = ImportSetting.objects.filter(workspace_id=workspace_id, import_code_fields__contains=[destination_type]).first() @@ -85,6 +89,11 @@ def disable_cost_centers(workspace_id: int, cost_centers_to_disable: Dict, *args cost_center_values = [] for cost_center_map in cost_centers_to_disable.values(): + if not use_code_in_naming and cost_center_map['value'] == cost_center_map['updated_value']: + continue + elif use_code_in_naming and (cost_center_map['value'] == cost_center_map['updated_value'] and cost_center_map['code'] == cost_center_map['update_code']): + continue + cost_center_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=cost_center_map['value'], code=cost_center_map['code']) cost_center_values.append(cost_center_name) @@ -96,9 +105,9 @@ def disable_cost_centers(workspace_id: int, cost_centers_to_disable: Dict, *args } expense_attribute_value_map = {} - for k, v in cost_centers_to_disable.items(): + for destination_id, v in cost_centers_to_disable.items(): cost_center_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=v['value'], code=v['code']) - expense_attribute_value_map[cost_center_name] = k + expense_attribute_value_map[cost_center_name] = destination_id expense_attributes = ExpenseAttribute.objects.filter(**filters) diff --git a/apps/mappings/imports/modules/merchants.py b/apps/mappings/imports/modules/merchants.py index 325d1fc..eccfcdd 100644 --- a/apps/mappings/imports/modules/merchants.py +++ b/apps/mappings/imports/modules/merchants.py @@ -75,7 +75,7 @@ def import_destination_attribute_to_fyle(self, import_log: ImportLog): self.sync_expense_attributes(platform) -def disable_merchants(workspace_id: int, merchants_to_disable: Dict, *args, **kwargs): +def disable_merchants(workspace_id: int, merchants_to_disable: Dict, is_import_to_fyle_enabled: bool = False, *args, **kwargs): """ merchants_to_disable object format: { @@ -87,12 +87,21 @@ def disable_merchants(workspace_id: int, merchants_to_disable: Dict, *args, **kw } } """ + if not is_import_to_fyle_enabled or len(merchants_to_disable) == 0: + logger.info("Skipping disabling merchants in Fyle | WORKSPACE_ID: %s", workspace_id) + return + fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) platform = PlatformConnector(fyle_credentials=fyle_credentials) use_code_in_naming = ImportSetting.objects.filter(workspace_id = workspace_id, import_code_fields__contains=['VENDOR']).first() merchant_values = [] for merchant_map in merchants_to_disable.values(): + if not use_code_in_naming and merchant_map['value'] == merchant_map['updated_value']: + continue + elif use_code_in_naming and (merchant_map['value'] == merchant_map['updated_value'] and merchant_map['code'] == merchant_map['update_code']): + continue + merchant_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=merchant_map['value'], code=merchant_map['code']) merchant_values.append(merchant_name) diff --git a/apps/mappings/imports/modules/projects.py b/apps/mappings/imports/modules/projects.py index 4649a3f..5ad7195 100644 --- a/apps/mappings/imports/modules/projects.py +++ b/apps/mappings/imports/modules/projects.py @@ -77,7 +77,7 @@ def construct_fyle_payload( return payload -def disable_projects(workspace_id: int, projects_to_disable: Dict, *args, **kwargs): +def disable_projects(workspace_id: int, projects_to_disable: Dict, is_import_to_fyle_enabled: bool = False, *args, **kwargs): """ Disable projects in Fyle when the projects are updated in Sage 300. This is a callback function that is triggered from accounting_mappings. @@ -92,6 +92,10 @@ def disable_projects(workspace_id: int, projects_to_disable: Dict, *args, **kwar } """ + if not is_import_to_fyle_enabled or len(projects_to_disable) == 0: + logger.info("Skipping disabling merchants in Fyle | WORKSPACE_ID: %s", workspace_id) + return + fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) platform = PlatformConnector(fyle_credentials=fyle_credentials) platform.projects.sync() @@ -103,6 +107,11 @@ def disable_projects(workspace_id: int, projects_to_disable: Dict, *args, **kwar project_values = [] for projects_map in projects_to_disable.values(): + if not use_code_in_naming and projects_map['value'] == projects_map['updated_value']: + continue + elif use_code_in_naming and (projects_map['value'] == projects_map['updated_value'] and projects_map['code'] == projects_map['update_code']): + continue + project_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=projects_map['value'], code=projects_map['code']) project_values.append(project_name) @@ -115,9 +124,9 @@ def disable_projects(workspace_id: int, projects_to_disable: Dict, *args, **kwar # Expense attribute value map is as follows: {old_project_name: destination_id} expense_attribute_value_map = {} - for k, v in projects_to_disable.items(): + for destination_id, v in projects_to_disable.items(): project_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=v['value'], code=v['code']) - expense_attribute_value_map[project_name] = k + expense_attribute_value_map[project_name] = destination_id expense_attributes = ExpenseAttribute.objects.filter(**filters) @@ -142,8 +151,9 @@ def disable_projects(workspace_id: int, projects_to_disable: Dict, *args, **kwar if bulk_payload: logger.info(f"Disabling Projects in Fyle | WORKSPACE_ID: {workspace_id} | COUNT: {len(bulk_payload)}") platform.projects.post_bulk(bulk_payload) + update_and_disable_cost_code(workspace_id, projects_to_disable, platform, use_code_in_naming) + platform.projects.sync() else: logger.info(f"No Projects to Disable in Fyle | WORKSPACE_ID: {workspace_id}") - update_and_disable_cost_code(workspace_id, projects_to_disable, platform, use_code_in_naming) - platform.projects.sync() + return bulk_payload diff --git a/apps/sage300/utils.py b/apps/sage300/utils.py index 4fa1542..2d64e7e 100644 --- a/apps/sage300/utils.py +++ b/apps/sage300/utils.py @@ -1,7 +1,7 @@ import logging from django.utils.module_loading import import_string from fyle_accounting_mappings.models import DestinationAttribute, MappingSetting -from apps.workspaces.models import Sage300Credential +from apps.workspaces.models import Sage300Credential, ImportSetting from sage_desktop_sdk.sage_desktop_sdk import SageDesktopSDK from apps.sage300.models import CostCategory from apps.mappings.models import Version @@ -131,7 +131,7 @@ def _remove_credit_card_vendors(self): logger.info(f'Deleting {vendor_count} credit card vendors from workspace_id {self.workspace_id}') credit_card_vendor.delete() - def _sync_data(self, data_gen, attribute_type, display_name, workspace_id, field_names, is_generator: bool = True, vendor_type_mapping = None): + def _sync_data(self, data_gen, attribute_type, display_name, workspace_id, field_names, is_generator: bool = True, vendor_type_mapping = None, is_import_to_fyle_enabled: bool = False): """ Synchronize data from Sage Desktop SDK to your application :param data: Data to synchronize @@ -159,7 +159,8 @@ def _sync_data(self, data_gen, attribute_type, display_name, workspace_id, field attribute_type, workspace_id, True, - attribute_disable_callback_path=ATTRIBUTE_CALLBACK_MAP[source_type] + attribute_disable_callback_path=ATTRIBUTE_CALLBACK_MAP[source_type], + is_import_to_fyle_enabled=is_import_to_fyle_enabled ) else: DestinationAttribute.bulk_create_or_update_destination_attributes( @@ -185,7 +186,10 @@ def sync_accounts(self): """ version = Version.objects.get(workspace_id=self.workspace_id).account accounts = self.connection.accounts.get_all(version=version) - self._sync_data(accounts, 'ACCOUNT', 'accounts', self.workspace_id, ['code', 'version']) + + is_import_to_fyle_enabled = self.is_imported_enabled('ACCOUNT', self.workspace_id) + + self._sync_data(accounts, 'ACCOUNT', 'accounts', self.workspace_id, ['code', 'version'], is_import_to_fyle_enabled=is_import_to_fyle_enabled) return [] def sync_vendors(self): @@ -201,6 +205,8 @@ def sync_vendors(self): vendor_types = None vendor_type_mapping = None + is_import_to_fyle_enabled = self.is_imported_enabled('VENDOR', self.workspace_id) + if not DestinationAttribute.objects.filter(workspace_id=self.workspace_id, attribute_type='VENDOR_TYPE').exists(): vendor_types = self.connection.vendors.get_vendor_types() self._sync_data(vendor_types, 'VENDOR_TYPE', 'vendor_type', self.workspace_id, ['version']) @@ -208,7 +214,7 @@ def sync_vendors(self): vendor_types = DestinationAttribute.objects.filter(workspace_id=self.workspace_id, attribute_type='VENDOR_TYPE').values('destination_id', 'value').distinct() vendor_type_mapping = {vendor_type['destination_id']: vendor_type['value'] for vendor_type in vendor_types} - self._sync_data(vendors, 'VENDOR', 'vendor', self.workspace_id, field_names, vendor_type_mapping=vendor_type_mapping) + self._sync_data(vendors, 'VENDOR', 'vendor', self.workspace_id, field_names, vendor_type_mapping=vendor_type_mapping, is_import_to_fyle_enabled=is_import_to_fyle_enabled) return [] def sync_jobs(self): @@ -220,7 +226,10 @@ def sync_jobs(self): field_names = [ 'code', 'status', 'version', 'account_prefix_id', 'created_on_utc' ] - self._sync_data(jobs, 'JOB', 'job', self.workspace_id, field_names) + + is_import_to_fyle_enabled = self.is_imported_enabled('JOB', self.workspace_id) + + self._sync_data(jobs, 'JOB', 'job', self.workspace_id, field_names, is_import_to_fyle_enabled=is_import_to_fyle_enabled) return [] def sync_standard_cost_codes(self): @@ -317,3 +326,28 @@ def get_source_type(self, attribute_type, workspace_id): source_type = 'CATEGORY' return source_type + + def is_imported_enabled(self, attribute_type, workspace_id): + """ + Check if import is enabled for the attribute type + :param attribute_type: Type of the attribute + :return: Whether import is enabled + """ + is_import_to_fyle_enabled = False + + import_settings = ImportSetting.objects.filter(workspace_id=self.workspace_id).first() + if not import_settings: + return is_import_to_fyle_enabled + + if attribute_type == 'ACCOUNT' and import_settings.import_categories: + is_import_to_fyle_enabled = True + + elif attribute_type == 'VENDOR' and import_settings.import_vendors_as_merchants: + is_import_to_fyle_enabled = True + + elif attribute_type == 'JOB': + mapping_setting = MappingSetting.objects.filter(workspace_id=workspace_id, destination_field='JOB').first() + if mapping_setting and mapping_setting.import_to_fyle: + is_import_to_fyle_enabled = True + + return is_import_to_fyle_enabled diff --git a/requirements.txt b/requirements.txt index d731406..c5f15d6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -28,7 +28,7 @@ fyle==0.37.0 # Reusable Fyle Packages fyle-rest-auth==1.7.2 -fyle-accounting-mappings==1.34.2 +fyle-accounting-mappings==1.34.3 fyle-integrations-platform-connector==1.39.0 diff --git a/tests/test_mappings/test_imports/test_modules/test_categories.py b/tests/test_mappings/test_imports/test_modules/test_categories.py index 3ddbdd5..7b364d0 100644 --- a/tests/test_mappings/test_imports/test_modules/test_categories.py +++ b/tests/test_mappings/test_imports/test_modules/test_categories.py @@ -177,7 +177,7 @@ def test_disable_categories( mock_platform = mocker.patch('apps.mappings.imports.modules.categories.PlatformConnector') bulk_post_call = mocker.patch.object(mock_platform.return_value.categories, 'post_bulk') - disable_categories(workspace_id, categories_to_disable) + disable_categories(workspace_id, categories_to_disable, is_import_to_fyle_enabled=True) assert bulk_post_call.call_count == 1 @@ -190,7 +190,7 @@ def test_disable_categories( } } - disable_categories(workspace_id, categories_to_disable) + disable_categories(workspace_id, categories_to_disable, is_import_to_fyle_enabled=True) assert bulk_post_call.call_count == 1 # Test disable projects with code in naming @@ -223,5 +223,5 @@ def test_disable_categories( 'id': 'source_id_123' }] - bulk_payload = disable_categories(workspace_id, categories_to_disable) + bulk_payload = disable_categories(workspace_id, categories_to_disable, is_import_to_fyle_enabled=True) assert bulk_payload == payload diff --git a/tests/test_mappings/test_imports/test_modules/test_cost_centers.py b/tests/test_mappings/test_imports/test_modules/test_cost_centers.py index f4b4d96..f4b1c2b 100644 --- a/tests/test_mappings/test_imports/test_modules/test_cost_centers.py +++ b/tests/test_mappings/test_imports/test_modules/test_cost_centers.py @@ -118,7 +118,7 @@ def test_disable_cost_centers( mock_platform = mocker.patch('apps.mappings.imports.modules.cost_centers.PlatformConnector') bulk_post_call = mocker.patch.object(mock_platform.return_value.cost_centers, 'post_bulk') - disable_cost_centers(workspace_id, cost_centers_to_disable) + disable_cost_centers(workspace_id, cost_centers_to_disable, is_import_to_fyle_enabled=True) assert bulk_post_call.call_count == 1 @@ -131,7 +131,7 @@ def test_disable_cost_centers( } } - disable_cost_centers(workspace_id, cost_centers_to_disable) + disable_cost_centers(workspace_id, cost_centers_to_disable, is_import_to_fyle_enabled=True) assert bulk_post_call.call_count == 1 # Test disable projects with code in naming @@ -167,5 +167,5 @@ def test_disable_cost_centers( } ] - bulk_payload = disable_cost_centers(workspace_id, cost_centers_to_disable) + bulk_payload = disable_cost_centers(workspace_id, cost_centers_to_disable, is_import_to_fyle_enabled=True) assert bulk_payload == payload diff --git a/tests/test_mappings/test_imports/test_modules/test_merchants.py b/tests/test_mappings/test_imports/test_modules/test_merchants.py index 327a3a2..d23d0dd 100644 --- a/tests/test_mappings/test_imports/test_modules/test_merchants.py +++ b/tests/test_mappings/test_imports/test_modules/test_merchants.py @@ -155,7 +155,7 @@ def test_disable_merchants( mock_platform = mocker.patch('apps.mappings.imports.modules.merchants.PlatformConnector') bulk_post_call = mocker.patch.object(mock_platform.return_value.merchants, 'post') - disable_merchants(workspace_id, merchants_to_disable) + disable_merchants(workspace_id, merchants_to_disable, is_import_to_fyle_enabled=True) assert bulk_post_call.call_count == 1 @@ -168,7 +168,7 @@ def test_disable_merchants( } } - disable_merchants(workspace_id, merchants_to_disable) + disable_merchants(workspace_id, merchants_to_disable, is_import_to_fyle_enabled=True) assert bulk_post_call.call_count == 1 # Test disable projects with code in naming @@ -196,5 +196,5 @@ def test_disable_merchants( payload = ['old_merchant_code: old_merchant'] - bulk_payload = disable_merchants(workspace_id, merchants_to_disable) + bulk_payload = disable_merchants(workspace_id, merchants_to_disable, is_import_to_fyle_enabled=True) assert bulk_payload[0] == payload[0] diff --git a/tests/test_sage300/test_helpers.py b/tests/test_sage300/test_helpers.py index 89bc4ae..cb8e84f 100644 --- a/tests/test_sage300/test_helpers.py +++ b/tests/test_sage300/test_helpers.py @@ -124,7 +124,7 @@ def test_disable_projects( disable_cost_code_call = mocker.patch('apps.sage300.dependent_fields.update_and_disable_cost_code') - disable_projects(workspace_id, projects_to_disable) + disable_projects(workspace_id, projects_to_disable, is_import_to_fyle_enabled=True) assert bulk_post_call.call_count == 1 assert sync_call.call_count == 2 @@ -139,10 +139,10 @@ def test_disable_projects( } } - disable_projects(workspace_id, projects_to_disable) + disable_projects(workspace_id, projects_to_disable, is_import_to_fyle_enabled=True) assert bulk_post_call.call_count == 1 - assert sync_call.call_count == 4 - disable_cost_code_call.call_count == 2 + assert sync_call.call_count == 3 + disable_cost_code_call.call_count == 1 # Test disable projects with code in naming import_settings = ImportSetting.objects.get(workspace_id=workspace_id) @@ -178,7 +178,7 @@ def test_disable_projects( 'id': 'source_id_123' }] - assert disable_projects(workspace_id, projects_to_disable) == payload + assert disable_projects(workspace_id, projects_to_disable, is_import_to_fyle_enabled=True) == payload def test_update_and_disable_cost_code( From 98b4ce6cbcd1f6024bfb1650560c994122e7bf64 Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari Date: Thu, 5 Sep 2024 16:55:50 +0530 Subject: [PATCH 02/12] typo fix --- apps/mappings/imports/modules/projects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mappings/imports/modules/projects.py b/apps/mappings/imports/modules/projects.py index 5ad7195..af2296c 100644 --- a/apps/mappings/imports/modules/projects.py +++ b/apps/mappings/imports/modules/projects.py @@ -93,7 +93,7 @@ def disable_projects(workspace_id: int, projects_to_disable: Dict, is_import_to_ """ if not is_import_to_fyle_enabled or len(projects_to_disable) == 0: - logger.info("Skipping disabling merchants in Fyle | WORKSPACE_ID: %s", workspace_id) + logger.info("Skipping disabling projects in Fyle | WORKSPACE_ID: %s", workspace_id) return fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) From 4aea04525bd83810fd71c609cf50c043de245bd4 Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari Date: Mon, 9 Sep 2024 14:32:20 +0530 Subject: [PATCH 03/12] update accounting mappings --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c5f15d6..ff27bde 100644 --- a/requirements.txt +++ b/requirements.txt @@ -28,7 +28,7 @@ fyle==0.37.0 # Reusable Fyle Packages fyle-rest-auth==1.7.2 -fyle-accounting-mappings==1.34.3 +fyle-accounting-mappings==1.34.4 fyle-integrations-platform-connector==1.39.0 From c0e68fb6a1d78a6050d29a0fb42d28f14c93c480 Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari Date: Sun, 15 Sep 2024 20:41:02 +0530 Subject: [PATCH 04/12] fix return type --- apps/sage300/dependent_fields.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/sage300/dependent_fields.py b/apps/sage300/dependent_fields.py index 9eb3644..28eb35c 100644 --- a/apps/sage300/dependent_fields.py +++ b/apps/sage300/dependent_fields.py @@ -75,7 +75,7 @@ def create_dependent_custom_field_in_fyle(workspace_id: int, fyle_attribute_type @handle_import_exceptions -def post_dependent_cost_code(import_log: ImportLog, dependent_field_setting: DependentFieldSetting, platform: PlatformConnector, filters: Dict, is_enabled: bool = True) -> List[str]: +def post_dependent_cost_code(import_log: ImportLog, dependent_field_setting: DependentFieldSetting, platform: PlatformConnector, filters: Dict, is_enabled: bool = True) -> tuple[List[str], bool]: import_settings = ImportSetting.objects.filter(workspace_id=import_log.workspace.id).first() use_job_code_in_naming = False use_cost_code_in_naming = False @@ -281,7 +281,7 @@ def update_and_disable_cost_code(workspace_id: int, cost_codes_to_disable: Dict, } cost_code_import_log = ImportLog.create('COST_CODE', workspace_id) # This call will disable the cost codes in Fyle that has old project name - posted_cost_codes = post_dependent_cost_code(cost_code_import_log, dependent_field_setting, platform, filters, is_enabled=False) + posted_cost_codes, _ = post_dependent_cost_code(cost_code_import_log, dependent_field_setting, platform, filters, is_enabled=False) logger.info(f"Disabled Cost Codes in Fyle | WORKSPACE_ID: {workspace_id} | COUNT: {len(posted_cost_codes)}") From 90afe7b205a5611ffd4af71a22e08eb6e112b2c0 Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari Date: Mon, 16 Sep 2024 09:58:52 +0530 Subject: [PATCH 05/12] update edit expenses condition --- apps/fyle/tasks.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/fyle/tasks.py b/apps/fyle/tasks.py index 66b7ed9..8459bad 100644 --- a/apps/fyle/tasks.py +++ b/apps/fyle/tasks.py @@ -128,19 +128,15 @@ def update_non_exported_expenses(data: Dict) -> None: """ To update expenses not in COMPLETE, IN_PROGRESS state """ - expense_state = None org_id = data['org_id'] expense_id = data['id'] workspace = Workspace.objects.get(org_id=org_id) expense = Expense.objects.filter(workspace_id=workspace.id, expense_id=expense_id).first() if expense: - if 'state' in expense.accounting_export_summary: - expense_state = expense.accounting_export_summary['state'] - else: - expense_state = 'NOT_EXPORTED' + accounting_export = AccountingExport.objects.filter(workspace_id=workspace.id, expense_id=expense.id).first() - if expense_state and expense_state not in ['COMPLETE', 'IN_PROGRESS']: + if accounting_export and accounting_export.status in ['EXPORT_READY', 'FAILED', 'FATAL']: expense_obj = [] expense_obj.append(data) expense_objects = FyleExpenses().construct_expense_object(expense_obj, expense.workspace_id) From 4ca097f6f54f79d4b5b1b1cc60af479fb5578dd7 Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari Date: Mon, 16 Sep 2024 10:28:34 +0530 Subject: [PATCH 06/12] fix test cases --- apps/fyle/tasks.py | 8 ++++++-- tests/test_fyle/test_tasks.py | 12 +++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/apps/fyle/tasks.py b/apps/fyle/tasks.py index 8459bad..be4efd6 100644 --- a/apps/fyle/tasks.py +++ b/apps/fyle/tasks.py @@ -134,9 +134,13 @@ def update_non_exported_expenses(data: Dict) -> None: expense = Expense.objects.filter(workspace_id=workspace.id, expense_id=expense_id).first() if expense: - accounting_export = AccountingExport.objects.filter(workspace_id=workspace.id, expense_id=expense.id).first() + accounting_export = AccountingExport.objects.filter( + workspace_id=workspace.id, + expenses=expense, + status__in=['EXPORT_READY', 'FAILED', 'FATAL'] + ).first() - if accounting_export and accounting_export.status in ['EXPORT_READY', 'FAILED', 'FATAL']: + if accounting_export: expense_obj = [] expense_obj.append(data) expense_objects = FyleExpenses().construct_expense_object(expense_obj, expense.workspace_id) diff --git a/tests/test_fyle/test_tasks.py b/tests/test_fyle/test_tasks.py index e2ba493..8065611 100644 --- a/tests/test_fyle/test_tasks.py +++ b/tests/test_fyle/test_tasks.py @@ -7,6 +7,7 @@ ) from apps.fyle.models import Expense from apps.workspaces.models import Workspace +from apps.accounting_exports.models import AccountingExport def test_update_non_exported_expenses(db, create_temp_workspace, mocker, api_client): @@ -29,6 +30,14 @@ def test_update_non_exported_expenses(db, create_temp_workspace, mocker, api_cli expense_created.accounting_export_summary = {} expense_created.save() + accounting_export, _ = AccountingExport.objects.update_or_create( + workspace_id=1, + type='PURCHASE_INVOICE', + status='EXPORT_READY' + ) + accounting_export.expenses.add(expense_created) + accounting_export.save() + workspace = Workspace.objects.filter(id=1).first() workspace.org_id = org_id workspace.save() @@ -40,7 +49,8 @@ def test_update_non_exported_expenses(db, create_temp_workspace, mocker, api_cli expense = Expense.objects.get(expense_id='txhJLOSKs1iN', org_id=org_id) assert expense.category == 'ABN Withholding' - expense.accounting_export_summary = {"synced": True, "state": "COMPLETE"} + accounting_export.status = 'COMPLETE' + accounting_export.save() expense.category = 'Old Category' expense.save() From 510429d1942fd57ddbebe567541d9d543a837a86 Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari Date: Tue, 17 Sep 2024 16:39:19 +0530 Subject: [PATCH 07/12] fix typo --- apps/mappings/imports/modules/categories.py | 4 ++-- apps/mappings/imports/modules/cost_centers.py | 4 ++-- apps/mappings/imports/modules/merchants.py | 4 ++-- apps/mappings/imports/modules/projects.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/mappings/imports/modules/categories.py b/apps/mappings/imports/modules/categories.py index 84e5612..72fdc34 100644 --- a/apps/mappings/imports/modules/categories.py +++ b/apps/mappings/imports/modules/categories.py @@ -98,7 +98,7 @@ def disable_categories(workspace_id: int, categories_to_disable: Dict, is_import 'value': 'old_category_name', 'updated_value': 'new_category_name', 'code': 'old_code', - 'update_code': 'new_code' ---- if the code is updated else same as code + 'updated_code': 'new_code' ---- if the code is updated else same as code } } """ @@ -115,7 +115,7 @@ def disable_categories(workspace_id: int, categories_to_disable: Dict, is_import for category_map in categories_to_disable.values(): if not use_code_in_naming and category_map['value'] == category_map['updated_value']: continue - elif use_code_in_naming and (category_map['value'] == category_map['updated_value'] and category_map['code'] == category_map['update_code']): + elif use_code_in_naming and (category_map['value'] == category_map['updated_value'] and category_map['code'] == category_map['updated_code']): continue category_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=category_map['value'], code=category_map['code']) diff --git a/apps/mappings/imports/modules/cost_centers.py b/apps/mappings/imports/modules/cost_centers.py index 581117f..bdd7b5d 100644 --- a/apps/mappings/imports/modules/cost_centers.py +++ b/apps/mappings/imports/modules/cost_centers.py @@ -73,7 +73,7 @@ def disable_cost_centers(workspace_id: int, cost_centers_to_disable: Dict, is_im 'value': 'old_cost_center_name', 'updated_value': 'new_cost_center_name', 'code': 'old_code', - 'update_code': 'new_code' ---- if the code is updated else same as code + 'updated_code': 'new_code' ---- if the code is updated else same as code } } """ @@ -91,7 +91,7 @@ def disable_cost_centers(workspace_id: int, cost_centers_to_disable: Dict, is_im for cost_center_map in cost_centers_to_disable.values(): if not use_code_in_naming and cost_center_map['value'] == cost_center_map['updated_value']: continue - elif use_code_in_naming and (cost_center_map['value'] == cost_center_map['updated_value'] and cost_center_map['code'] == cost_center_map['update_code']): + elif use_code_in_naming and (cost_center_map['value'] == cost_center_map['updated_value'] and cost_center_map['code'] == cost_center_map['updated_code']): continue cost_center_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=cost_center_map['value'], code=cost_center_map['code']) diff --git a/apps/mappings/imports/modules/merchants.py b/apps/mappings/imports/modules/merchants.py index eccfcdd..f7606ee 100644 --- a/apps/mappings/imports/modules/merchants.py +++ b/apps/mappings/imports/modules/merchants.py @@ -83,7 +83,7 @@ def disable_merchants(workspace_id: int, merchants_to_disable: Dict, is_import_t 'value': 'old_merchant_name', 'updated_value': 'new_merchant_name', 'code': 'old_code', - 'update_code': 'new_code' ---- if the code is updated else same as code + 'updated_code': 'new_code' ---- if the code is updated else same as code } } """ @@ -99,7 +99,7 @@ def disable_merchants(workspace_id: int, merchants_to_disable: Dict, is_import_t for merchant_map in merchants_to_disable.values(): if not use_code_in_naming and merchant_map['value'] == merchant_map['updated_value']: continue - elif use_code_in_naming and (merchant_map['value'] == merchant_map['updated_value'] and merchant_map['code'] == merchant_map['update_code']): + elif use_code_in_naming and (merchant_map['value'] == merchant_map['updated_value'] and merchant_map['code'] == merchant_map['updated_code']): continue merchant_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=merchant_map['value'], code=merchant_map['code']) diff --git a/apps/mappings/imports/modules/projects.py b/apps/mappings/imports/modules/projects.py index af2296c..a96f908 100644 --- a/apps/mappings/imports/modules/projects.py +++ b/apps/mappings/imports/modules/projects.py @@ -109,7 +109,7 @@ def disable_projects(workspace_id: int, projects_to_disable: Dict, is_import_to_ for projects_map in projects_to_disable.values(): if not use_code_in_naming and projects_map['value'] == projects_map['updated_value']: continue - elif use_code_in_naming and (projects_map['value'] == projects_map['updated_value'] and projects_map['code'] == projects_map['update_code']): + elif use_code_in_naming and (projects_map['value'] == projects_map['updated_value'] and projects_map['code'] == projects_map['updated_code']): continue project_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=projects_map['value'], code=projects_map['code']) From 6f2871a55580b0d22939f6a1ad960c345722492f Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari Date: Tue, 17 Sep 2024 17:20:16 +0530 Subject: [PATCH 08/12] bump platform connector version --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ff27bde..6b45728 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,7 +29,7 @@ fyle==0.37.0 # Reusable Fyle Packages fyle-rest-auth==1.7.2 fyle-accounting-mappings==1.34.4 -fyle-integrations-platform-connector==1.39.0 +fyle-integrations-platform-connector==1.39.1 # Postgres Dependincies From 7641ef25f99ca3a01986ce10f23d44c1f3ef2359 Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari Date: Tue, 17 Sep 2024 17:47:17 +0530 Subject: [PATCH 09/12] loggers for test --- apps/mappings/imports/modules/merchants.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/mappings/imports/modules/merchants.py b/apps/mappings/imports/modules/merchants.py index f7606ee..dd6fe4b 100644 --- a/apps/mappings/imports/modules/merchants.py +++ b/apps/mappings/imports/modules/merchants.py @@ -94,12 +94,14 @@ def disable_merchants(workspace_id: int, merchants_to_disable: Dict, is_import_t fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) platform = PlatformConnector(fyle_credentials=fyle_credentials) use_code_in_naming = ImportSetting.objects.filter(workspace_id = workspace_id, import_code_fields__contains=['VENDOR']).first() - + logger.info(f"Inside disable_merchants | WORKSPACE_ID: {workspace_id} | USE_CODE_IN_NAMING: {use_code_in_naming}") merchant_values = [] for merchant_map in merchants_to_disable.values(): if not use_code_in_naming and merchant_map['value'] == merchant_map['updated_value']: + logger.info(f"Skipping2 disabling merchant {merchant_map['value']} in Fyle | WORKSPACE_ID: {workspace_id}") continue elif use_code_in_naming and (merchant_map['value'] == merchant_map['updated_value'] and merchant_map['code'] == merchant_map['updated_code']): + logger.info(f"Skipping3 disabling merchant {merchant_map['value']} in Fyle | WORKSPACE_ID: {workspace_id}") continue merchant_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=merchant_map['value'], code=merchant_map['code']) @@ -111,9 +113,10 @@ def disable_merchants(workspace_id: int, merchants_to_disable: Dict, is_import_t 'value__in': merchant_values, 'active': True } + logger.info("Filters: %s", filters) bulk_payload = ExpenseAttribute.objects.filter(**filters).values_list('value', flat=True) - + logger.info("Bulk Payload: %s", bulk_payload) if bulk_payload: logger.info(f"Disabling Merchants in Fyle | WORKSPACE_ID: {workspace_id} | COUNT: {len(bulk_payload)}") platform.merchants.post(bulk_payload, delete_merchants=True) From 4ccd2510cc4cc9873619d71ad3759f302e4b9c8b Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari Date: Tue, 17 Sep 2024 18:09:52 +0530 Subject: [PATCH 10/12] add logger --- apps/sage300/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/sage300/utils.py b/apps/sage300/utils.py index 2d64e7e..f0f7d5e 100644 --- a/apps/sage300/utils.py +++ b/apps/sage300/utils.py @@ -206,7 +206,7 @@ def sync_vendors(self): vendor_type_mapping = None is_import_to_fyle_enabled = self.is_imported_enabled('VENDOR', self.workspace_id) - + logger.info(f'is_import_to_fyle_enabled: {is_import_to_fyle_enabled}') if not DestinationAttribute.objects.filter(workspace_id=self.workspace_id, attribute_type='VENDOR_TYPE').exists(): vendor_types = self.connection.vendors.get_vendor_types() self._sync_data(vendor_types, 'VENDOR_TYPE', 'vendor_type', self.workspace_id, ['version']) From 34c2b4d1a37b98e07d0d73fee8700574a753d3c4 Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari Date: Tue, 17 Sep 2024 18:21:23 +0530 Subject: [PATCH 11/12] Revert "loggers for test" This reverts commit 7641ef25f99ca3a01986ce10f23d44c1f3ef2359. --- apps/mappings/imports/modules/merchants.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/mappings/imports/modules/merchants.py b/apps/mappings/imports/modules/merchants.py index dd6fe4b..f7606ee 100644 --- a/apps/mappings/imports/modules/merchants.py +++ b/apps/mappings/imports/modules/merchants.py @@ -94,14 +94,12 @@ def disable_merchants(workspace_id: int, merchants_to_disable: Dict, is_import_t fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id) platform = PlatformConnector(fyle_credentials=fyle_credentials) use_code_in_naming = ImportSetting.objects.filter(workspace_id = workspace_id, import_code_fields__contains=['VENDOR']).first() - logger.info(f"Inside disable_merchants | WORKSPACE_ID: {workspace_id} | USE_CODE_IN_NAMING: {use_code_in_naming}") + merchant_values = [] for merchant_map in merchants_to_disable.values(): if not use_code_in_naming and merchant_map['value'] == merchant_map['updated_value']: - logger.info(f"Skipping2 disabling merchant {merchant_map['value']} in Fyle | WORKSPACE_ID: {workspace_id}") continue elif use_code_in_naming and (merchant_map['value'] == merchant_map['updated_value'] and merchant_map['code'] == merchant_map['updated_code']): - logger.info(f"Skipping3 disabling merchant {merchant_map['value']} in Fyle | WORKSPACE_ID: {workspace_id}") continue merchant_name = prepend_code_to_name(prepend_code_in_name=use_code_in_naming, value=merchant_map['value'], code=merchant_map['code']) @@ -113,10 +111,9 @@ def disable_merchants(workspace_id: int, merchants_to_disable: Dict, is_import_t 'value__in': merchant_values, 'active': True } - logger.info("Filters: %s", filters) bulk_payload = ExpenseAttribute.objects.filter(**filters).values_list('value', flat=True) - logger.info("Bulk Payload: %s", bulk_payload) + if bulk_payload: logger.info(f"Disabling Merchants in Fyle | WORKSPACE_ID: {workspace_id} | COUNT: {len(bulk_payload)}") platform.merchants.post(bulk_payload, delete_merchants=True) From 2cbfe177c0243b0382374b65f7699553ee8ff44c Mon Sep 17 00:00:00 2001 From: Hrishabh Tiwari Date: Tue, 17 Sep 2024 18:21:31 +0530 Subject: [PATCH 12/12] Revert "add logger" This reverts commit 4ccd2510cc4cc9873619d71ad3759f302e4b9c8b. --- apps/sage300/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/sage300/utils.py b/apps/sage300/utils.py index f0f7d5e..2d64e7e 100644 --- a/apps/sage300/utils.py +++ b/apps/sage300/utils.py @@ -206,7 +206,7 @@ def sync_vendors(self): vendor_type_mapping = None is_import_to_fyle_enabled = self.is_imported_enabled('VENDOR', self.workspace_id) - logger.info(f'is_import_to_fyle_enabled: {is_import_to_fyle_enabled}') + if not DestinationAttribute.objects.filter(workspace_id=self.workspace_id, attribute_type='VENDOR_TYPE').exists(): vendor_types = self.connection.vendors.get_vendor_types() self._sync_data(vendor_types, 'VENDOR_TYPE', 'vendor_type', self.workspace_id, ['version'])