Skip to content

Commit

Permalink
Business central auth fixed (#61)
Browse files Browse the repository at this point in the history
* Business central auth fixed

* Company Selection API (#62)

* Company Selection API

* test case fixed

* moved to business central
  • Loading branch information
ruuushhh authored Jan 2, 2024
1 parent b965983 commit 9d2d9bc
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 56 deletions.
7 changes: 3 additions & 4 deletions apps/business_central/helpers.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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:
Expand Down
26 changes: 26 additions & 0 deletions apps/business_central/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 2 additions & 1 deletion apps/business_central/urls.py
Original file line number Diff line number Diff line change
@@ -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(
Expand All @@ -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')
]
7 changes: 4 additions & 3 deletions apps/business_central/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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):
Expand Down
13 changes: 12 additions & 1 deletion apps/business_central/views.py
Original file line number Diff line number Diff line change
@@ -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):
Expand All @@ -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
26 changes: 1 addition & 25 deletions apps/workspaces/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)

Expand Down Expand Up @@ -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(
Expand All @@ -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
20 changes: 0 additions & 20 deletions apps/workspaces/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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):
"""
Expand Down
20 changes: 19 additions & 1 deletion apps/workspaces/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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):
Expand Down
22 changes: 22 additions & 0 deletions tests/test_business_central/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 9d2d9bc

Please sign in to comment.