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

moving views logic to actions #255

Merged
merged 2 commits into from
Aug 28, 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
75 changes: 75 additions & 0 deletions apps/fyle/actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from fyle_accounting_mappings.models import ExpenseAttribute
from django.db.models import Q

from apps.tasks.models import TaskLog
from apps.workspaces.models import FyleCredential, WorkspaceGeneralSettings, Workspace
from apps.workspaces.serializers import WorkspaceSerializer
from datetime import datetime, timezone
from .models import Expense, ExpenseGroup, ExpenseGroupSettings

from fyle_integrations_platform_connector import PlatformConnector

def get_expense_field(workspace_id):

default_attributes = ['EMPLOYEE', 'CATEGORY', 'PROJECT', 'COST_CENTER', 'CORPORATE_CARD', 'TAX_GROUP']
attributes = ExpenseAttribute.objects.filter(
~Q(attribute_type__in=default_attributes),
workspace_id=workspace_id
).values('attribute_type', 'display_name').distinct()

expense_fields= [
{'attribute_type': 'COST_CENTER', 'display_name': 'Cost Center'},
{'attribute_type': 'PROJECT', 'display_name': 'Project'}
]

for attribute in attributes:
expense_fields.append(attribute)

return expense_fields


def sync_fyle_dimension(workspace_id):

workspace = Workspace.objects.get(id=workspace_id)
if workspace.source_synced_at:
time_interval = datetime.now(timezone.utc) - workspace.source_synced_at

if workspace.source_synced_at is None or time_interval.days > 0:
fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id)

platform = PlatformConnector(fyle_credentials)
platform.import_fyle_dimensions()

workspace.source_synced_at = datetime.now()
workspace.save(update_fields=['source_synced_at'])


def refresh_fyle_dimension(workspace_id):

fyle_credentials = FyleCredential.objects.get(workspace_id=workspace_id)

platform = PlatformConnector(fyle_credentials)
platform.import_fyle_dimensions()

workspace = Workspace.objects.get(id=workspace_id)
workspace.source_synced_at = datetime.now()
workspace.save(update_fields=['source_synced_at'])


def exportable_expense_group(workspace_id):

configuration = WorkspaceGeneralSettings.objects.get(workspace_id=workspace_id)
fund_source = []

if configuration.reimbursable_expenses_object:
fund_source.append('PERSONAL')
if configuration.corporate_credit_card_expenses_object:
fund_source.append('CCC')

expense_group_ids = ExpenseGroup.objects.filter(
workspace_id=workspace_id,
exported_at__isnull=True,
fund_source__in=fund_source
).values_list('id', flat=True)

return expense_group_ids
68 changes: 8 additions & 60 deletions apps/fyle/views.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
from datetime import datetime, timezone
from django.db.models import Q

from rest_framework.views import status
from rest_framework import generics
from rest_framework.response import Response

from fyle_accounting_mappings.models import ExpenseAttribute
from fyle_accounting_mappings.serializers import ExpenseAttributeSerializer

from fyle_integrations_platform_connector import PlatformConnector

from apps.tasks.models import TaskLog
from apps.workspaces.models import FyleCredential, WorkspaceGeneralSettings, Workspace
from apps.workspaces.serializers import WorkspaceSerializer

from fyle_integrations_platform_connector import PlatformConnector
from .tasks import create_expense_groups, get_task_log_and_fund_source, async_create_expense_groups
from .tasks import get_task_log_and_fund_source, async_create_expense_groups
from .models import Expense, ExpenseGroup, ExpenseGroupSettings
from .serializers import ExpenseGroupSerializer, ExpenseSerializer, ExpenseFieldSerializer, \
from .serializers import ExpenseGroupSerializer, ExpenseFieldSerializer, \
ExpenseGroupSettingsSerializer
from apps.exceptions import handle_view_exceptions
from .actions import exportable_expense_group, get_expense_field, refresh_fyle_dimension, sync_fyle_dimension


class ExpenseGroupView(generics.ListCreateAPIView):
Expand Down Expand Up @@ -98,19 +86,8 @@ class ExpenseFieldsView(generics.ListAPIView):
serializer_class = ExpenseFieldSerializer

def get(self, request, *args, **kwargs):
default_attributes = ['EMPLOYEE', 'CATEGORY', 'PROJECT', 'COST_CENTER', 'CORPORATE_CARD', 'TAX_GROUP']
attributes = ExpenseAttribute.objects.filter(
~Q(attribute_type__in=default_attributes),
workspace_id=self.kwargs['workspace_id']
).values('attribute_type', 'display_name').distinct()

expense_fields= [
{'attribute_type': 'COST_CENTER', 'display_name': 'Cost Center'},
{'attribute_type': 'PROJECT', 'display_name': 'Project'}
]

for attribute in attributes:
expense_fields.append(attribute)
expense_fields = get_expense_field(workspace_id=kwargs['workspace_id'])

return Response(
expense_fields,
Expand Down Expand Up @@ -146,18 +123,7 @@ def post(self, request, *args, **kwargs):
Sync Data From Fyle
"""

workspace = Workspace.objects.get(id=kwargs['workspace_id'])
if workspace.source_synced_at:
time_interval = datetime.now(timezone.utc) - workspace.source_synced_at

if workspace.source_synced_at is None or time_interval.days > 0:
fyle_credentials = FyleCredential.objects.get(workspace_id=kwargs['workspace_id'])

platform = PlatformConnector(fyle_credentials)
platform.import_fyle_dimensions()

workspace.source_synced_at = datetime.now()
workspace.save(update_fields=['source_synced_at'])
sync_fyle_dimension(workspace_id=kwargs['workspace_id'])

return Response(
status=status.HTTP_200_OK
Expand All @@ -174,15 +140,8 @@ def post(self, request, *args, **kwargs):
"""
Sync data from Fyle
"""

fyle_credentials = FyleCredential.objects.get(workspace_id=kwargs['workspace_id'])

platform = PlatformConnector(fyle_credentials)
platform.import_fyle_dimensions()

workspace = Workspace.objects.get(id=kwargs['workspace_id'])
workspace.source_synced_at = datetime.now()
workspace.save(update_fields=['source_synced_at'])
refresh_fyle_dimension(workspace_id=kwargs['workspace_id'])

return Response(
status=status.HTTP_200_OK
Expand All @@ -194,19 +153,8 @@ class ExportableExpenseGroupsView(generics.RetrieveAPIView):
List Exportable Expense Groups
"""
def get(self, request, *args, **kwargs):
configuration = WorkspaceGeneralSettings.objects.get(workspace_id=kwargs['workspace_id'])
fund_source = []

if configuration.reimbursable_expenses_object:
fund_source.append('PERSONAL')
if configuration.corporate_credit_card_expenses_object:
fund_source.append('CCC')

expense_group_ids = ExpenseGroup.objects.filter(
workspace_id=self.kwargs['workspace_id'],
exported_at__isnull=True,
fund_source__in=fund_source
).values_list('id', flat=True)

expense_group_ids = exportable_expense_group(workspace_id=kwargs['workspace_id'])

return Response(
data={'exportable_expense_group_ids': expense_group_ids},
Expand Down
48 changes: 48 additions & 0 deletions apps/mappings/actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import logging
from .serializers import TenantMappingSerializer, GeneralMappingSerializer
from .models import TenantMapping, GeneralMapping
from apps.workspaces.models import XeroCredentials
from apps.xero.utils import XeroConnector
from apps.workspaces.models import Workspace
from ..workspaces.models import WorkspaceGeneralSettings

from django_q.tasks import Chain

from xerosdk.exceptions import UnsuccessfulAuthentication

from .utils import MappingUtils


logger = logging.getLogger(__name__)

def tenant_mapping_view(workspace_id, tenant_mapping_payload):

mapping_utils = MappingUtils(workspace_id)
tenant_mapping_object = mapping_utils.create_or_update_tenant_mapping(tenant_mapping_payload)
xero_credentials = XeroCredentials.objects.filter(workspace_id=workspace_id).first()
workspace = Workspace.objects.filter(id=workspace_id).first()

try:
xero_connector = XeroConnector(xero_credentials, workspace_id=workspace_id)
tenant_mapping = TenantMapping.objects.filter(workspace_id=workspace_id).first()
company_info = xero_connector.get_organisations()[0]
workspace.xero_currency = company_info['BaseCurrency']
workspace.save()
xero_credentials.country = company_info['CountryCode']
xero_credentials.save()

if tenant_mapping and not tenant_mapping.connection_id:
connections = xero_connector.connection.connections.get_all()
connection = list(filter(lambda connection: connection['tenantId'] == tenant_mapping.tenant_id, connections))

if connection:
tenant_mapping.connection_id = connection[0]['id']
tenant_mapping.save()

except UnsuccessfulAuthentication:
logger.info('Xero refresh token is invalid for workspace_id - %s', workspace_id)

Check warning on line 43 in apps/mappings/actions.py

View check run for this annotation

Codecov / codecov/patch

apps/mappings/actions.py#L43

Added line #L43 was not covered by tests

except Exception:
logger.info('Error while fetching company information')

return tenant_mapping_object
39 changes: 4 additions & 35 deletions apps/mappings/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,11 @@

from fyle_xero_api.utils import assert_valid

from xerosdk.exceptions import UnsuccessfulAuthentication

from .serializers import TenantMappingSerializer, GeneralMappingSerializer
from .models import TenantMapping, GeneralMapping
from apps.workspaces.models import XeroCredentials
from .utils import MappingUtils
from .serializers import TenantMappingSerializer
from .models import TenantMapping
from ..workspaces.models import WorkspaceGeneralSettings
from apps.xero.utils import XeroConnector
from apps.workspaces.models import Workspace
from apps.exceptions import handle_view_exceptions
from .actions import tenant_mapping_view

logger = logging.getLogger(__name__)

Expand All @@ -35,33 +30,7 @@ def post(self, request, *args, **kwargs):

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

mapping_utils = MappingUtils(kwargs['workspace_id'])
tenant_mapping_object = mapping_utils.create_or_update_tenant_mapping(tenant_mapping_payload)
xero_credentials = XeroCredentials.objects.filter(workspace_id=kwargs['workspace_id']).first()
workspace = Workspace.objects.filter(id=kwargs['workspace_id']).first()

try:
xero_connector = XeroConnector(xero_credentials, workspace_id=kwargs['workspace_id'])
tenant_mapping = TenantMapping.objects.filter(workspace_id=kwargs['workspace_id']).first()
company_info = xero_connector.get_organisations()[0]
workspace.xero_currency = company_info['BaseCurrency']
workspace.save()
xero_credentials.country = company_info['CountryCode']
xero_credentials.save()

if tenant_mapping and not tenant_mapping.connection_id:
connections = xero_connector.connection.connections.get_all()
connection = list(filter(lambda connection: connection['tenantId'] == tenant_mapping.tenant_id, connections))

if connection:
tenant_mapping.connection_id = connection[0]['id']
tenant_mapping.save()

except UnsuccessfulAuthentication:
logger.info('Xero refresh token is invalid for workspace_id - %s', kwargs['workspace_id'])

except Exception:
logger.info('Error while fetching company information')
tenant_mapping_object = tenant_mapping_view(workspace_id=kwargs['workspace_id'],tenant_mapping_payload=tenant_mapping_payload)

return Response(
data=self.serializer_class(tenant_mapping_object).data,
Expand Down
Loading
Loading