From 1c6f0b3cf8bc5ce98b55613d85dea9670a939f8f Mon Sep 17 00:00:00 2001 From: ruuushhh <66899387+ruuushhh@users.noreply.github.com> Date: Tue, 14 Nov 2023 17:08:26 +0530 Subject: [PATCH] Import Standard Cost Code, Standard Category as Cost Center (#66) --- apps/mappings/imports/modules/base.py | 2 + apps/mappings/imports/modules/cost_centers.py | 57 +++++++++++++++++++ apps/mappings/imports/tasks.py | 2 + tests/conftest.py | 30 ++++++++++ .../test_imports/test_modules/fixtures.py | 15 +++++ .../test_modules/test_cost_centers.py | 21 +++++++ 6 files changed, 127 insertions(+) create mode 100644 apps/mappings/imports/modules/cost_centers.py create mode 100644 tests/test_mappings/test_imports/test_modules/test_cost_centers.py diff --git a/apps/mappings/imports/modules/base.py b/apps/mappings/imports/modules/base.py index f503ff41..d21d8d68 100644 --- a/apps/mappings/imports/modules/base.py +++ b/apps/mappings/imports/modules/base.py @@ -187,6 +187,8 @@ def construct_payload_and_import_to_fyle( """ Construct Payload and Import to fyle in Batches """ + is_auto_sync_status_allowed = self.get_auto_sync_permission() + filters = self.construct_attributes_filter(self.destination_field) destination_attributes_count = DestinationAttribute.objects.filter(**filters).count() diff --git a/apps/mappings/imports/modules/cost_centers.py b/apps/mappings/imports/modules/cost_centers.py new file mode 100644 index 00000000..18a7d29b --- /dev/null +++ b/apps/mappings/imports/modules/cost_centers.py @@ -0,0 +1,57 @@ +from datetime import datetime +from typing import List +from apps.mappings.imports.modules.base import Base +from fyle_accounting_mappings.models import DestinationAttribute + + +class CostCenter(Base): + """ + Class for Cost Center module + """ + + def __init__(self, workspace_id: int, destination_field: str, sync_after: datetime): + super().__init__( + workspace_id=workspace_id, + source_field="COST_CENTER", + destination_field=destination_field, + platform_class_name="cost_centers", + sync_after=sync_after, + ) + + def trigger_import(self): + """ + Trigger import for Cost Center module + """ + self.check_import_log_and_start_import() + + def construct_fyle_payload( + self, + paginated_destination_attributes: List[DestinationAttribute], + existing_fyle_attributes_map: object, + is_auto_sync_status_allowed: bool + ): + """ + Construct Fyle payload for CostCenter module + :param paginated_destination_attributes: List of paginated destination attributes + :param existing_fyle_attributes_map: Existing Fyle attributes map + :param is_auto_sync_status_allowed: Is auto sync status allowed + :return: Fyle payload + """ + payload = [] + + for attribute in paginated_destination_attributes: + cost_center = { + 'name': attribute.value, + 'code': attribute.destination_id, + 'is_enabled': True if attribute.active is None else attribute.active, + 'description': 'Cost Center - {0}, Id - {1}'.format( + attribute.value, + attribute.destination_id + ) + } + + # Create a new cost-center if it does not exist in Fyle + if attribute.value.lower() not in existing_fyle_attributes_map: + payload.append(cost_center) + + return payload diff --git a/apps/mappings/imports/tasks.py b/apps/mappings/imports/tasks.py index bcfc35a7..9a490797 100644 --- a/apps/mappings/imports/tasks.py +++ b/apps/mappings/imports/tasks.py @@ -5,6 +5,7 @@ from apps.mappings.models import ImportLog from apps.mappings.imports.modules.categories import Category from apps.mappings.imports.modules.projects import Project +from apps.mappings.imports.modules.cost_centers import CostCenter from apps.mappings.imports.modules.expense_custom_fields import ExpenseCustomField from apps.fyle.models import DependentFieldSetting @@ -12,6 +13,7 @@ SOURCE_FIELD_CLASS_MAP = { 'CATEGORY': Category, 'PROJECT': Project, + 'COST_CENTER': CostCenter } diff --git a/tests/conftest.py b/tests/conftest.py index 854bf6e7..ac3a87ba 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -309,6 +309,36 @@ def add_project_mappings(): ) +@pytest.fixture() +@pytest.mark.django_db(databases=['default']) +def add_cost_center_mappings(): + """ + Pytest fixtue to add cost center mappings to a workspace + """ + workspace_ids = [ + 1, 2, 3 + ] + for workspace_id in workspace_ids: + DestinationAttribute.objects.create( + workspace_id=workspace_id, + attribute_type='COST_CENTER', + display_name='Direct Mail Campaign', + value='Direct Mail Campaign', + destination_id='10064', + detail='Cost Center - Direct Mail Campaign, Id - 10064', + active=True + ) + DestinationAttribute.objects.create( + workspace_id=workspace_id, + attribute_type='COST_CENTER', + display_name='Platform APIs', + value='Platform APIs', + destination_id='10081', + detail='Cost Center - Platform APIs, Id - 10081', + active=True + ) + + @pytest.fixture() @pytest.mark.django_db(databases=['default']) def add_export_settings(): diff --git a/tests/test_mappings/test_imports/test_modules/fixtures.py b/tests/test_mappings/test_imports/test_modules/fixtures.py index 4f83520c..7315a2bc 100644 --- a/tests/test_mappings/test_imports/test_modules/fixtures.py +++ b/tests/test_mappings/test_imports/test_modules/fixtures.py @@ -29,5 +29,20 @@ 'is_enabled': False, 'name': 'Platform APIs' } + ], + "create_fyle_cost_center_payload_create_new_case": + [ + { + 'code': '10064', + 'description': 'Cost Center - Direct Mail Campaign, Id - 10064', + 'is_enabled': True, + 'name': 'Direct Mail Campaign' + }, + { + 'description': 'Cost Center - Platform APIs, Id - 10081', + 'is_enabled': True, + 'name': 'Platform APIs', + 'code': '10081', + } ] } 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 new file mode 100644 index 00000000..1a1dbed3 --- /dev/null +++ b/tests/test_mappings/test_imports/test_modules/test_cost_centers.py @@ -0,0 +1,21 @@ +from apps.mappings.imports.modules.cost_centers import CostCenter +from fyle_accounting_mappings.models import DestinationAttribute +from .fixtures import data + + +def test_construct_fyle_payload(api_client, test_connection, mocker, create_temp_workspace, add_sage300_creds, add_fyle_credentials, add_cost_center_mappings): + cost_center = CostCenter(1, 'COST_CENTER', None) + + # create new case + paginated_destination_attributes = DestinationAttribute.objects.filter(workspace_id=1, attribute_type='COST_CENTER') + + existing_fyle_attributes_map = {} + is_auto_sync_status_allowed = cost_center.get_auto_sync_permission() + + fyle_payload = cost_center.construct_fyle_payload( + paginated_destination_attributes, + existing_fyle_attributes_map, + is_auto_sync_status_allowed + ) + + assert fyle_payload == data['create_fyle_cost_center_payload_create_new_case']