Skip to content

Commit

Permalink
Django filters for fyle app (#258)
Browse files Browse the repository at this point in the history
* django filter for xero-app

* change in test cases

* test case cahnge

* django filter for fyle app

* using generics

* resolving comments

* removed test case

* django filter for mappings app and test changes

* django filter for task app and test changes

* django filter for workspaces app and test changes

---------

Co-authored-by: Ashutosh619-sudo <[email protected]>
  • Loading branch information
Ashutosh619-sudo and Ashutosh619-sudo authored Sep 11, 2023
1 parent 6e3cf8d commit 0ce8cee
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 285 deletions.
69 changes: 10 additions & 59 deletions apps/fyle/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,77 +8,28 @@
ExpenseGroupSettingsSerializer
from apps.exceptions import handle_view_exceptions
from .actions import exportable_expense_group, get_expense_field, refresh_fyle_dimension, sync_fyle_dimension
from fyle_xero_api.utils import LookupFieldMixin


class ExpenseGroupView(generics.ListCreateAPIView):
class ExpenseGroupView(LookupFieldMixin, generics.ListCreateAPIView):
"""
List Fyle Expenses
"""
serializer_class = ExpenseGroupSerializer

def get_queryset(self):
state = self.request.query_params.get('state', 'ALL')
start_date = self.request.query_params.get('start_date', None)
end_date = self.request.query_params.get('end_date', None)
exported_at = self.request.query_params.get('exported_at', None)
expense_group_ids = self.request.query_params.get('expense_group_ids', None)

if expense_group_ids:
return ExpenseGroup.objects.filter(
workspace_id=self.kwargs['workspace_id'],
id__in=expense_group_ids.split(',')
)

if state == 'ALL':
return ExpenseGroup.objects.filter(workspace_id=self.kwargs['workspace_id']).order_by('-updated_at')

if state == 'FAILED':
return ExpenseGroup.objects.filter(tasklog__status='FAILED',
workspace_id=self.kwargs['workspace_id']).order_by('-updated_at')

elif state == 'COMPLETE':
filters = {
'workspace_id': self.kwargs['workspace_id'],
'tasklog__status': 'COMPLETE'
}

if start_date and end_date:
filters['exported_at__range'] = [start_date, end_date]

if exported_at:
filters['exported_at__gte'] = exported_at

return ExpenseGroup.objects.filter(**filters).order_by('-exported_at')

elif state == 'READY':
return ExpenseGroup.objects.filter(
workspace_id=self.kwargs['workspace_id'],
bill__id__isnull=True,
banktransaction__id__isnull=True
).order_by('-updated_at')
queryset = ExpenseGroup.objects.filter(tasklog__status='COMPLETE')
serializer_class = ExpenseGroupSerializer
filterset_fields = {'exported_at': {'gte', 'lte'}}
ordering_fields = ('-updated_at',)


class ExpenseGroupSettingsView(generics.ListCreateAPIView):
class ExpenseGroupSettingsView(generics.RetrieveAPIView):
"""
Expense Group Settings View
"""
lookup_field = 'workspace_id'
lookup_url_kwarg = 'workspace_id'
serializer_class = ExpenseGroupSettingsSerializer

def get(self, request, *args, **kwargs):
expense_group_settings = ExpenseGroupSettings.objects.get(workspace_id=self.kwargs['workspace_id'])

return Response(
data=self.serializer_class(expense_group_settings).data,
status=status.HTTP_200_OK
)

def post(self, request, *args, **kwargs):
expense_group_settings, _ = ExpenseGroupSettings.update_expense_group_settings(
request.data, self.kwargs['workspace_id'])
return Response(
data=self.serializer_class(expense_group_settings).data,
status=status.HTTP_200_OK
)
queryset = ExpenseGroupSettings.objects.all()


class ExpenseFieldsView(generics.ListAPIView):
Expand Down
20 changes: 6 additions & 14 deletions apps/mappings/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@
logger = logging.getLogger(__name__)


class TenantMappingView(generics.ListCreateAPIView):
class TenantMappingView(generics.CreateAPIView, generics.RetrieveAPIView):
"""
Tenant mappings view
"""

lookup_field = 'workspace_id'
lookup_url_kwarg = 'workspace_id'
serializer_class = TenantMappingSerializer
queryset = TenantMapping.objects.all()


def post(self, request, *args, **kwargs):
"""
Expand All @@ -37,19 +42,6 @@ def post(self, request, *args, **kwargs):
status=status.HTTP_200_OK
)

@handle_view_exceptions()
def get(self, request, *args, **kwargs):
"""
Get tenant mappings
"""

subsidiary_mapping = TenantMapping.objects.get(workspace_id=kwargs['workspace_id'])

return Response(
data=self.serializer_class(subsidiary_mapping).data,
status=status.HTTP_200_OK
)


class AutoMapEmployeeView(generics.CreateAPIView):
"""
Expand Down
30 changes: 5 additions & 25 deletions apps/tasks/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,14 @@

from .models import TaskLog
from .serializers import TaskLogSerializer
from fyle_xero_api.utils import LookupFieldMixin


class TasksView(generics.ListAPIView):
class TasksView(LookupFieldMixin,generics.ListAPIView):
"""
Tasks view
"""
serializer_class = TaskLogSerializer

def get_queryset(self):
"""
Return task logs in workspace
"""
task_type = self.request.query_params.get('task_type')
expense_group_ids = self.request.query_params.get('expense_group_ids')
task_status = self.request.query_params.get('status')

filters = {
'workspace_id': self.kwargs['workspace_id']
}

if task_type:
filters['type__in'] = task_type.split(',')

if expense_group_ids:
filters['expense_group_id__in'] = expense_group_ids.split(',')

if task_status:
filters['status__in'] = task_status.split(',')

return TaskLog.objects.filter(**filters).order_by('-updated_at').all()

queryset = TaskLog.objects.all()
filterset_fields = {'type':{'exact', 'in'}, 'expense_group_id':{'exact', 'in'}, 'status':{'exact', 'in'}}
ordering_fields = ('updated_at',)
22 changes: 11 additions & 11 deletions apps/workspaces/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
RevokeXeroConnectionView, XeroExternalSignUpsView, ExportToXeroView, LastExportDetailView

urlpatterns = [
path('', WorkspaceView.as_view({'get': 'get', 'post': 'post'})),
path('ready/', ReadyView.as_view({'get': 'get'})),
path('<int:workspace_id>/', WorkspaceView.as_view({'get': 'get_by_id'})),
path('<int:workspace_id>/connect_xero/authorization_code/', ConnectXeroView.as_view({'post': 'post'})),
path('<int:workspace_id>/credentials/xero/', ConnectXeroView.as_view({'get': 'get'})),
path('<int:workspace_id>/connection/xero/revoke/', RevokeXeroConnectionView.as_view({'post': 'post'})),
path('<int:workspace_id>/exports/trigger/', ExportToXeroView.as_view({'post': 'post'}), name='export-to-xero'),
path('<int:workspace_id>/settings/general/', GeneralSettingsView.as_view({'post': 'post', 'get': 'get', 'patch': 'patch'})),
path('', WorkspaceView.as_view()),
path('ready/', ReadyView.as_view()),
path('<int:workspace_id>/', WorkspaceView.as_view()),
path('<int:workspace_id>/connect_xero/authorization_code/', ConnectXeroView.as_view()),
path('<int:workspace_id>/credentials/xero/', ConnectXeroView.as_view()),
path('<int:workspace_id>/connection/xero/revoke/', RevokeXeroConnectionView.as_view()),
path('<int:workspace_id>/exports/trigger/', ExportToXeroView.as_view(), name='export-to-xero'),
path('<int:workspace_id>/settings/general/', GeneralSettingsView.as_view()),
path('<int:workspace_id>/fyle/', include('apps.fyle.urls')),
path('<int:workspace_id>/tasks/', include('apps.tasks.urls')),
path('<int:workspace_id>/xero/', include('apps.xero.urls')),
path('<int:workspace_id>/mappings/', include('apps.mappings.urls')),
path('<int:workspace_id>/admins/', WorkspaceAdminsView.as_view({'get': 'get'}), name='admin'),
path('external_signup/', XeroExternalSignUpsView.as_view({'post': 'post'})),
path('<int:workspace_id>/export_detail/', LastExportDetailView.as_view({'get': 'get'}), name='export-detail'),
path('<int:workspace_id>/admins/', WorkspaceAdminsView.as_view(), name='admin'),
path('external_signup/', XeroExternalSignUpsView.as_view()),
path('<int:workspace_id>/export_detail/', LastExportDetailView.as_view(), name='export-detail'),
]
108 changes: 21 additions & 87 deletions apps/workspaces/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from .tasks import export_to_xero
from apps.exceptions import handle_view_exceptions
from .actions import connect_xero, post_workspace, revoke_connections, get_workspace_admin
from rest_framework import generics

logger = logging.getLogger(__name__)

Expand All @@ -26,7 +27,7 @@
auth_utils = AuthUtils()


class ReadyView(viewsets.ViewSet):
class ReadyView(generics.ListAPIView):
"""
Ready call
"""
Expand All @@ -48,7 +49,7 @@ def get(self, request):
)


class WorkspaceView(viewsets.ViewSet):
class WorkspaceView(generics.CreateAPIView, generics.RetrieveUpdateAPIView):
"""
Xero Workspace
"""
Expand Down Expand Up @@ -80,21 +81,6 @@ def get(self, request):
status=status.HTTP_200_OK
)

@handle_view_exceptions()
def get_by_id(self, request, **kwargs):
"""
Get Workspace by id
"""

user = User.objects.get(user_id=request.user)
workspace = Workspace.objects.get(pk=kwargs['workspace_id'], user=user)

return Response(
data=WorkspaceSerializer(workspace).data if workspace else {},
status=status.HTTP_200_OK
)


def patch(self, request, **kwargs):
"""
PATCH workspace
Expand All @@ -111,7 +97,7 @@ def patch(self, request, **kwargs):
)


class ConnectXeroView(viewsets.ViewSet):
class ConnectXeroView(generics.CreateAPIView, generics.RetrieveAPIView):
"""
Xero Connect Oauth View
"""
Expand All @@ -130,7 +116,8 @@ def post(self, request, **kwargs):
data=XeroCredentialSerializer(xero_credentials).data,
status=status.HTTP_200_OK
)



@handle_view_exceptions()
def get(self, request, **kwargs):
"""
Expand All @@ -143,9 +130,9 @@ def get(self, request, **kwargs):
data=XeroCredentialSerializer(xero_credentials).data,
status=status.HTTP_200_OK
)



class RevokeXeroConnectionView(viewsets.ViewSet):
class RevokeXeroConnectionView(generics.CreateAPIView):
"""
Xero Revoke Xero Connection View
"""
Expand All @@ -164,57 +151,18 @@ def post(self, request, **kwargs):
)


class GeneralSettingsView(viewsets.ViewSet):
class GeneralSettingsView(generics.RetrieveAPIView):
"""
General Settings
"""
lookup_field = 'workspace_id'
lookup_url_kwarg = 'workspace_id'
serializer_class = WorkSpaceGeneralSettingsSerializer
queryset = WorkspaceGeneralSettings.objects.all()

def post(self, request, *args, **kwargs):
"""
Post workspace general settings
"""
general_settings_payload = request.data

assert_valid(general_settings_payload is not None, 'Request body is empty')

workspace_id = kwargs['workspace_id']

general_settings = create_or_update_general_settings(general_settings_payload, workspace_id)
return Response(
data=self.serializer_class(general_settings).data,
status=status.HTTP_200_OK
)

@handle_view_exceptions()
def get(self, request, *args, **kwargs):
"""
Get workspace general settings
"""

general_settings = self.queryset.get(workspace_id=kwargs['workspace_id'])
return Response(
data=self.serializer_class(general_settings).data,
status=status.HTTP_200_OK
)

def patch(self, request, **kwargs):
"""
PATCH workspace general settings
"""
workspace_general_settings_object = WorkspaceGeneralSettings.objects.get(workspace_id=kwargs['workspace_id'])
serializer = WorkSpaceGeneralSettingsSerializer(
workspace_general_settings_object, data=request.data, partial=True
)
if serializer.is_valid():
serializer.save()
return Response(
data=serializer.data,
status=status.HTTP_200_OK
)


class XeroExternalSignUpsView(viewsets.ViewSet):
class XeroExternalSignUpsView(generics.CreateAPIView):
"""
Xero External Sign Ups
"""
Expand All @@ -237,7 +185,7 @@ def post(self, request, **kwargs):
)


class ExportToXeroView(viewsets.ViewSet):
class ExportToXeroView(generics.CreateAPIView):
"""
Export Expenses to QBO
"""
Expand All @@ -250,32 +198,18 @@ def post(self, request, *args, **kwargs):
)


class LastExportDetailView(viewsets.ViewSet):
class LastExportDetailView(generics.RetrieveAPIView):
"""
Last Export Details
"""
serializer_class = LastExportDetailSerializer

def get(self, request, *args, **kwargs):
"""
last export detail
"""
last_export_detail = LastExportDetail.objects.filter(workspace_id=kwargs['workspace_id']).first()
if last_export_detail and last_export_detail.last_exported_at and last_export_detail.total_expense_groups_count:
return Response(
data=self.serializer_class(last_export_detail).data,
status=status.HTTP_200_OK
)
else:
return Response(
data={
'message': 'latest exported details does not exist in workspace'
},
status=status.HTTP_400_BAD_REQUEST
)

lookup_field = 'workspace_id'
lookup_url_kwarg = 'workspace_id'
serializer_class = LastExportDetailSerializer
queryset = LastExportDetail.objects.filter(last_exported_at__isnull=False, total_expense_groups_count__gt=0)


class WorkspaceAdminsView(viewsets.ViewSet):
class WorkspaceAdminsView(generics.ListAPIView):

def get(self, request, *args, **kwargs):
"""
Expand Down
Loading

0 comments on commit 0ce8cee

Please sign in to comment.