From ee85c74bdba5e9d69190cba0cbf5577903b84938 Mon Sep 17 00:00:00 2001 From: ruuushhh Date: Tue, 2 Jan 2024 09:19:15 +0530 Subject: [PATCH 1/2] Business central auth fixed --- apps/workspaces/helpers.py | 26 +------------------------- apps/workspaces/serializers.py | 20 -------------------- apps/workspaces/views.py | 20 +++++++++++++++++++- 3 files changed, 20 insertions(+), 46 deletions(-) diff --git a/apps/workspaces/helpers.py b/apps/workspaces/helpers.py index ea0b851..6ddcd1a 100644 --- a/apps/workspaces/helpers.py +++ b/apps/workspaces/helpers.py @@ -7,8 +7,7 @@ from dynamics.exceptions.dynamics_exceptions import InternalServerError, InvalidTokenError from future.moves.urllib.parse import urlencode -from apps.business_central.utils import BusinessCentralConnector -from apps.workspaces.models import BusinessCentralCredentials, Workspace +from apps.workspaces.models import BusinessCentralCredentials logger = logging.getLogger(__name__) @@ -89,8 +88,6 @@ def connect_business_central(authorization_code, redirect_uri, workspace_id): # Retrieve or create BusinessCentralCredentials based on workspace_id business_central_credentials = BusinessCentralCredentials.objects.filter(workspace_id=workspace_id).first() - workspace = Workspace.objects.get(pk=workspace_id) - if not business_central_credentials: # If BusinessCentralCredentials does not exist, create a new one business_central_credentials = BusinessCentralCredentials.objects.create( @@ -102,25 +99,4 @@ def connect_business_central(authorization_code, redirect_uri, workspace_id): business_central_credentials.is_expired = False business_central_credentials.save() - if workspace and not workspace.business_central_company_id: - # If workspace has no associated Business Central company ID, fetch and update it - business_central_connector = BusinessCentralConnector(business_central_credentials, workspace_id=workspace_id) - connections = business_central_connector.connection.connections.get_all() - connection = list( - filter( - lambda connection: connection["id"] == workspace.business_central_company_id, - connections, - ) - ) - - if connection: - # If a matching connection is found, update workspace's Business Central company ID - workspace.business_central_company_id = connection[0]["id"] - workspace.save() - - if workspace.onboarding_state == "COMPANY_SELECTION": - # If workspace's onboarding state is "COMPANY_SELECTION", update it to "EXPORT_SETTINGS" - workspace.onboarding_state = "EXPORT_SETTINGS" - workspace.save() - return business_central_credentials diff --git a/apps/workspaces/serializers.py b/apps/workspaces/serializers.py index 2eb7331..743e8ea 100644 --- a/apps/workspaces/serializers.py +++ b/apps/workspaces/serializers.py @@ -9,7 +9,6 @@ from apps.fyle.helpers import get_cluster_domain from apps.users.models import User -from apps.workspaces.helpers import connect_business_central from apps.workspaces.models import ( AdvancedSetting, BusinessCentralCredentials, @@ -85,25 +84,6 @@ class Meta: model = BusinessCentralCredentials fields = "__all__" - def create(self, validated_data): - """ - Create Business Central Credentials - """ - try: - workspace_id = self.context['request'].parser_context.get('kwargs').get('workspace_id') - authorization_code = self.context['request'].data.get('code') - redirect_uri = self.context['request'].data.get('redirect_uri') - - business_central_credentials = connect_business_central( - authorization_code=authorization_code, - redirect_uri=redirect_uri, - workspace_id=workspace_id, - ) - - return business_central_credentials - except Exception as exception: - raise serializers.ValidationError(exception) - class ExportSettingsSerializer(serializers.ModelSerializer): """ diff --git a/apps/workspaces/views.py b/apps/workspaces/views.py index 510e9ef..e956701 100644 --- a/apps/workspaces/views.py +++ b/apps/workspaces/views.py @@ -5,6 +5,7 @@ from rest_framework import generics from rest_framework.views import Response, status +from apps.workspaces.helpers import connect_business_central from apps.workspaces.models import AdvancedSetting, BusinessCentralCredentials, ExportSetting, ImportSetting, Workspace from apps.workspaces.serializers import ( AdvancedSettingSerializer, @@ -77,7 +78,24 @@ class ConnectBusinessCentralView(generics.CreateAPIView, generics.RetrieveAPIVie serializer_class = BusinessCentralCredentialSerializer lookup_field = 'workspace_id' - queryset = BusinessCentralCredentials.objects.all() + def post(self, request, **kwargs): + """ + Create Business Central Credentials + """ + + business_central_credentials = connect_business_central( + authorization_code=request.data.get("code"), + redirect_uri=request.data.get("redirect_uri"), + workspace_id=kwargs["workspace_id"], + ) + + return Response( + data=BusinessCentralCredentialSerializer(business_central_credentials).data, + status=status.HTTP_200_OK, + ) + + def get_queryset(self): + return BusinessCentralCredentials.objects.all() class ExportSettingView(generics.CreateAPIView, generics.RetrieveAPIView): From 8bcf89440e197fe53d1a8c0770828153f94f81b8 Mon Sep 17 00:00:00 2001 From: ruuushhh <66899387+ruuushhh@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:53:55 +0530 Subject: [PATCH 2/2] Company Selection API (#62) * Company Selection API * test case fixed * moved to business central --- apps/business_central/helpers.py | 7 +++-- apps/business_central/serializers.py | 26 +++++++++++++++++++ apps/business_central/urls.py | 3 ++- apps/business_central/utils.py | 7 ++--- apps/business_central/views.py | 13 +++++++++- tests/test_business_central/test_views.py | 22 ++++++++++++++++ .../test_expense_custom_fields.py | 1 - 7 files changed, 69 insertions(+), 10 deletions(-) diff --git a/apps/business_central/helpers.py b/apps/business_central/helpers.py index 6a7db1b..57a0ee0 100644 --- a/apps/business_central/helpers.py +++ b/apps/business_central/helpers.py @@ -1,11 +1,10 @@ -from datetime import datetime, timezone import logging +from datetime import datetime, timezone from django.utils.module_loading import import_string -from apps.workspaces.models import Workspace, BusinessCentralCredentials - +from apps.workspaces.models import BusinessCentralCredentials, Workspace logger = logging.getLogger(__name__) logger.level = logging.INFO @@ -49,7 +48,7 @@ def sync_dimensions(business_central_credential: BusinessCentralCredentials, wor business_central_connection = import_string('apps.business_central.utils.BusinessCentralConnector')(business_central_credential, workspace_id) # List of dimensions to sync - dimensions = ['accounts', 'vendors', 'employees', 'locations'] + dimensions = ['accounts', 'vendors', 'employees', 'locations', 'companies'] for dimension in dimensions: try: diff --git a/apps/business_central/serializers.py b/apps/business_central/serializers.py index 74d9033..cf03f86 100644 --- a/apps/business_central/serializers.py +++ b/apps/business_central/serializers.py @@ -93,3 +93,29 @@ def format_business_central_fields(self, workspace_id): attributes_list = list(serialized_attributes) return attributes_list + + +class CompanySelectionSerializer(serializers.ModelSerializer): + """ + Company Selection Serializer + """ + + class Meta: + model = Workspace + fields = '__all__' + read_only_fields = ('id', 'name', 'org_id', 'created_at', 'updated_at', 'user') + + def create(self, validated_data): + """ + Create Company Selection + """ + workspace_id = self.context['request'].parser_context.get('kwargs').get('workspace_id') + workspace = Workspace.objects.get(id=workspace_id) + + workspace.business_central_company_id = self.context['request'].data.get('company_id') + workspace.business_central_company_name = self.context['request'].data.get('company_name') + if workspace.onboarding_state == 'COMPANY_SELECTION': + workspace.onboarding_state = 'EXPORT_SETTINGS' + workspace.save() + + return workspace diff --git a/apps/business_central/urls.py b/apps/business_central/urls.py index 10ec578..f2e10f1 100644 --- a/apps/business_central/urls.py +++ b/apps/business_central/urls.py @@ -1,6 +1,6 @@ from django.urls import path -from apps.business_central.views import BusinessCentralFieldsView, ImportBusinessCentralAttributesView +from apps.business_central.views import BusinessCentralFieldsView, CompanySelectionView, ImportBusinessCentralAttributesView urlpatterns = [ path( @@ -9,4 +9,5 @@ name="import-business-central-attributes", ), path("fields/", BusinessCentralFieldsView.as_view(), name="business-central-fields"), + path('company/', CompanySelectionView.as_view(), name='company-selection') ] diff --git a/apps/business_central/utils.py b/apps/business_central/utils.py index ecdb99f..0b29cd3 100644 --- a/apps/business_central/utils.py +++ b/apps/business_central/utils.py @@ -61,14 +61,14 @@ def _sync_data(self, data, attribute_type, display_name, workspace_id, field_nam destination_attributes = [] for item in data: detail = {field: item[field] for field in field_names} - if (attribute_type == 'EMPLOYEE' and item.get('status') == 'Active') or (attribute_type == 'LOCATION') or (item.get('blocked') and item['blocked'] != True): + if (attribute_type == 'EMPLOYEE' and item.get('status') == 'Active') or (attribute_type in ('LOCATION', 'COMPANY')) or (item.get('blocked') and item['blocked'] != True): active = True else: active = False destination_attributes.append(self._create_destination_attribute( attribute_type, display_name, - item['displayName'], + item['displayName'] if item['displayName'] else item['name'], item['id'], active, detail @@ -81,8 +81,9 @@ def sync_companies(self): sync business central companies """ companies = self.connection.companies.get_all() + field_names = [] - self._sync_data(companies, 'COMPANY', 'company', self.workspace_id) + self._sync_data(companies, 'COMPANY', 'company', self.workspace_id, field_names) return [] def sync_accounts(self): diff --git a/apps/business_central/views.py b/apps/business_central/views.py index 94fbcb8..f2674e9 100644 --- a/apps/business_central/views.py +++ b/apps/business_central/views.py @@ -1,6 +1,10 @@ from rest_framework import generics -from apps.business_central.serializers import BusinessCentralFieldSerializer, ImportBusinessCentralAttributesSerializer +from apps.business_central.serializers import ( + BusinessCentralFieldSerializer, + CompanySelectionSerializer, + ImportBusinessCentralAttributesSerializer, +) class ImportBusinessCentralAttributesView(generics.CreateAPIView): @@ -19,3 +23,10 @@ class BusinessCentralFieldsView(generics.ListAPIView): def get_queryset(self): return BusinessCentralFieldSerializer().format_business_central_fields(self.kwargs["workspace_id"]) + + +class CompanySelectionView(generics.CreateAPIView): + """ + Retrieve Company Selection + """ + serializer_class = CompanySelectionSerializer diff --git a/tests/test_business_central/test_views.py b/tests/test_business_central/test_views.py index 0cd41eb..a554052 100644 --- a/tests/test_business_central/test_views.py +++ b/tests/test_business_central/test_views.py @@ -40,3 +40,25 @@ def test_business_central_fields(api_client, test_connection, create_temp_worksp assert response.status_code == 200 assert response.data == [{'attribute_type': 'DUMMY_ATTRIBUTE_TYPE', 'display_name': 'dummy_attribute_name'}] + + +def test_post_company_selection(api_client, test_connection): + ''' + Test get workspace admins + ''' + url = reverse('workspaces') + api_client.credentials(HTTP_AUTHORIZATION='Bearer {}'.format(test_connection.access_token)) + response = api_client.post(url) + + workspace_id = response.data['id'] + + url = reverse('company-selection', kwargs={'workspace_id': workspace_id}) + api_client.credentials(HTTP_AUTHORIZATION='Bearer {}'.format(test_connection.access_token)) + + payload = { + 'company_id': '123', + 'company_name': 'Fyle Technologies' + } + + response = api_client.post(url, payload) + assert response.status_code == 201 diff --git a/tests/test_mappings/test_imports/test_modules/test_expense_custom_fields.py b/tests/test_mappings/test_imports/test_modules/test_expense_custom_fields.py index c2bd5a1..08f3186 100644 --- a/tests/test_mappings/test_imports/test_modules/test_expense_custom_fields.py +++ b/tests/test_mappings/test_imports/test_modules/test_expense_custom_fields.py @@ -195,7 +195,6 @@ def test_construct_fyle_expense_custom_field_payload( fyle_payload = expense_custom_field.construct_fyle_expense_custom_field_payload( paginated_destination_attributes, platform ) - print(fyle_payload, "fyle_payload") assert ( fyle_payload