Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for sage300 expense fields api #40

Merged
merged 25 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ COPY . /fyle-sage-desktop-api/
WORKDIR /fyle-sage-desktop-api

# Do linting checks
# RUN flake8 .
RUN flake8 .

# Expose development port
EXPOSE 8000
Expand Down
59 changes: 55 additions & 4 deletions apps/sage300/serializers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import logging
from django.db.models import Q
from datetime import datetime
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.views import status

from fyle_accounting_mappings.models import DestinationAttribute

from apps.workspaces.models import Workspace, Sage300Credential
from apps.sage300.helpers import sync_dimensions, check_interval_and_sync_dimension

Expand All @@ -27,7 +30,9 @@ def create(self, validated_data):

# Retrieve the workspace and Sage 300 credentials
workspace = Workspace.objects.get(pk=workspace_id)
sage_intacct_credentials = Sage300Credential.objects.get(workspace_id=workspace.id)
sage_intacct_credentials = Sage300Credential.objects.get(
workspace_id=workspace.id
)

if refresh_dimension:
# If 'refresh' is true, perform a full sync of dimensions
Expand All @@ -45,10 +50,56 @@ def create(self, validated_data):

except Sage300Credential.DoesNotExist:
# Handle the case when Sage 300 credentials are not found or invalid
raise serializers.ValidationError({'message': 'Sage300 credentials not found / invalid in workspace'})
raise serializers.ValidationError(
{'message': 'Sage300 credentials not found / invalid in workspace'}
)

except Exception as exception:
# Handle unexpected exceptions and log the error
logger.error('Something unexpected happened workspace_id: %s %s', workspace_id, exception)
logger.error(
'Something unexpected happened workspace_id: %s %s',
workspace_id,
exception,
)
# Raise a custom exception or re-raise the original exception
raise Exception()
raise


class DestinationAttributeSerializer(serializers.Serializer):
attribute_type = serializers.CharField()
display_name = serializers.CharField()


class Sage300FieldSerializer(serializers.Serializer):
"""
Sage300 Expense Fields Serializer
"""

attribute_type = serializers.CharField()
display_name = serializers.CharField()

def format_sage300_fields(self, workspace_id):
attribute_types = [
"VENDOR",
"ACCOUNT",
"JOB",
"CATEGORY",
"COST_CODE",
"PAYMENT",
]
attributes = (
DestinationAttribute.objects.filter(
~Q(attribute_type__in=attribute_types),
workspace_id=workspace_id,
)
.values("attribute_type", "display_name")
.distinct()
)

serialized_attributes = Sage300FieldSerializer(attributes, many=True).data

# Adding "Job" by default since it can be supported even if it doesn't exist
attributes_list = list(serialized_attributes)
attributes_list.append({"attribute_type": "JOB", "display_name": "Job"})

return attributes_list
10 changes: 7 additions & 3 deletions apps/sage300/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@

from django.urls import path

from apps.sage300.views import ImportSage300AttributesView
from apps.sage300.views import ImportSage300AttributesView, Sage300FieldsView


urlpatterns = [
path('import_attributes/', ImportSage300AttributesView.as_view(), name='import-sage300-attributes'),
path(
"import_attributes/",
ImportSage300AttributesView.as_view(),
name="import-sage300-attributes",
),
path("fields/", Sage300FieldsView.as_view(), name="sage300-fields"),
]
13 changes: 12 additions & 1 deletion apps/sage300/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

from rest_framework import generics

from apps.sage300.serializers import Sage300FieldSerializer
from apps.sage300.serializers import ImportSage300AttributesSerializer


logger = logging.getLogger(__name__)
logger.level = logging.INFO

Expand All @@ -12,5 +14,14 @@ class ImportSage300AttributesView(generics.CreateAPIView):
"""
Import Sage300 Attributes View
"""

serializer_class = ImportSage300AttributesSerializer


class Sage300FieldsView(generics.ListAPIView):
"""
Sage300 Expense Fields View
"""
serializer_class = Sage300FieldSerializer

def get_queryset(self):
NileshPant1999 marked this conversation as resolved.
Show resolved Hide resolved
return Sage300FieldSerializer().format_sage300_fields(self.kwargs["workspace_id"])
2 changes: 0 additions & 2 deletions sage_desktop_api/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,6 @@
}
}



CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
Expand Down
2 changes: 0 additions & 2 deletions sage_desktop_api/tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,9 @@
FYLE_APP_URL = os.environ.get('APP_URL')
FYLE_EXPENSE_URL = os.environ.get('FYLE_APP_URL')


SD_API_KEY = os.environ.get('SD_API_KEY')
SD_API_SECRET = os.environ.get('SD_API_SECRET')


# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/

Expand Down
25 changes: 16 additions & 9 deletions tests/test_sage300/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,11 @@ def test_sync_dimensions(api_client, test_connection, mocker, create_temp_worksp
workspace_id = 1

access_token = test_connection.access_token
url = reverse(
'import-sage300-attributes', kwargs={
'workspace_id': workspace_id
}
)
url = reverse('import-sage300-attributes', kwargs={'workspace_id': workspace_id})

api_client.credentials(HTTP_AUTHORIZATION='Bearer {}'.format(access_token))

mocker.patch(
'apps.sage300.helpers.sync_dimensions',
return_value=None
)
mocker.patch('apps.sage300.helpers.sync_dimensions', return_value=None)

response = api_client.post(url)
assert response.status_code == 201
Expand All @@ -32,3 +25,17 @@ def test_sync_dimensions(api_client, test_connection, mocker, create_temp_worksp

response = json.loads(response.content)
assert response['message'] == 'Sage300 credentials not found / invalid in workspace'


def test_sage300_fields(api_client, test_connection):
workspace_id = 1

access_token = test_connection.access_token
url = reverse('sage300-fields', kwargs={'workspace_id': workspace_id})

api_client.credentials(HTTP_AUTHORIZATION='Bearer {}'.format(access_token))

response = api_client.get(url)
assert response.status_code == 200

assert response.data['results'] == [{'attribute_type': 'JOB', 'display_name': 'Job'}]
Loading