diff --git a/apps/workspaces/apis/map_employees/__init__.py b/apps/workspaces/apis/map_employees/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/workspaces/apis/map_employees/serializers.py b/apps/workspaces/apis/map_employees/serializers.py new file mode 100644 index 00000000..14f36ab6 --- /dev/null +++ b/apps/workspaces/apis/map_employees/serializers.py @@ -0,0 +1,55 @@ +from apps.workspaces.apis.map_employees.triggers import MapEmployeesTriggers +from apps.workspaces.models import Configuration, Workspace +from rest_framework import serializers + + +class ConfigurationSerializer(serializers.ModelSerializer): + class Meta: + model = Configuration + fields = ['employee_field_mapping', 'auto_map_employees'] + + +class MapEmployeesSerializer(serializers.ModelSerializer): + + configuration = ConfigurationSerializer() + workspace_id = serializers.SerializerMethodField() + + class Meta: + model = Workspace + fields = ['configuration', 'workspace_id'] + read_only_fields = ['workspace_id'] + + def get_workspace_id(self, instance): + return instance.id + + def update(self, instance, validated_data): + + workspace_id = instance.id + configuration = validated_data.pop('configuration') + + configuration_instance = Configuration.objects.filter(workspace_id=workspace_id).first() + + if configuration_instance and (configuration_instance.employee_field_mapping != configuration['employee_field_mapping']): + configuration_instance.reimbursable_expenses_object = None + configuration_instance.save() + + configuration_instance, _ = Configuration.objects.update_or_create( + workspace_id=workspace_id, defaults={'employee_field_mapping': configuration['employee_field_mapping'], 'auto_map_employees': configuration['auto_map_employees']} + ) + + MapEmployeesTriggers.run_configurations_triggers(configuration=configuration_instance) + + if instance.onboarding_state == 'MAP_EMPLOYEES': + instance.onboarding_state = 'EXPORT_SETTINGS' + instance.save() + + return instance + + def validate(self,data): + if not data.get('configuration').get('employee_field_mapping'): + raise serializers.ValidationError('employee_field_mapping field is required') + + if data.get('configuration').get('auto_map_employees') and data.get('configuration').get('auto_map_employees') not in ['EMAIL', 'NAME', 'EMPLOYEE_CODE']: + raise serializers.ValidationError('auto_map_employees can have only EMAIL / NAME / EMPLOYEE_CODE') + + return data diff --git a/apps/workspaces/apis/map_employees/triggers.py b/apps/workspaces/apis/map_employees/triggers.py new file mode 100644 index 00000000..6d930cba --- /dev/null +++ b/apps/workspaces/apis/map_employees/triggers.py @@ -0,0 +1,10 @@ +from apps.mappings.tasks import schedule_auto_map_employees +from apps.workspaces.models import Configuration + + +class MapEmployeesTriggers: + + @staticmethod + def run_configurations_triggers(configuration: Configuration): + + schedule_auto_map_employees(configuration.auto_map_employees, configuration.workspace.id) diff --git a/apps/workspaces/apis/map_employees/views.py b/apps/workspaces/apis/map_employees/views.py new file mode 100644 index 00000000..d749196e --- /dev/null +++ b/apps/workspaces/apis/map_employees/views.py @@ -0,0 +1,11 @@ +from rest_framework import generics +from apps.workspaces.apis.map_employees.serializers import MapEmployeesSerializer +from apps.workspaces.models import Workspace + + +class MapEmployeesView(generics.RetrieveUpdateAPIView): + + serializer_class = MapEmployeesSerializer + + def get_object(self): + return Workspace.objects.filter(id=self.kwargs['workspace_id']).first() diff --git a/apps/workspaces/apis/urls.py b/apps/workspaces/apis/urls.py new file mode 100644 index 00000000..80934c77 --- /dev/null +++ b/apps/workspaces/apis/urls.py @@ -0,0 +1,8 @@ +from django.urls import path + +from apps.workspaces.apis.map_employees.views import MapEmployeesView + + +urlpatterns = [ + path('/map_employees/', MapEmployeesView.as_view()), +] diff --git a/apps/workspaces/migrations/0035_auto_20231019_1025.py b/apps/workspaces/migrations/0035_auto_20231019_1025.py new file mode 100644 index 00000000..7366e722 --- /dev/null +++ b/apps/workspaces/migrations/0035_auto_20231019_1025.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.14 on 2023-10-19 10:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('workspaces', '0034_auto_20231012_0750'), + ] + + operations = [ + migrations.AlterField( + model_name='configuration', + name='reimbursable_expenses_object', + field=models.CharField(choices=[('EXPENSE REPORT', 'EXPENSE REPORT'), ('JOURNAL ENTRY', 'JOURNAL ENTRY'), ('BILL', 'BILL')], help_text='Reimbursable Expenses type', max_length=50, null=True), + ), + ] diff --git a/apps/workspaces/models.py b/apps/workspaces/models.py index 92e71072..1409e6f9 100644 --- a/apps/workspaces/models.py +++ b/apps/workspaces/models.py @@ -144,7 +144,7 @@ class Configuration(models.Model): max_length=50, choices=EMPLOYEE_FIELD_MAPPING_CHOICES, help_text='Employee field mapping', null=True ) reimbursable_expenses_object = models.CharField( - max_length=50, choices=REIMBURSABLE_EXPENSES_OBJECT_CHOICES, help_text='Reimbursable Expenses type' + max_length=50, choices=REIMBURSABLE_EXPENSES_OBJECT_CHOICES, help_text='Reimbursable Expenses type', null=True ) corporate_credit_card_expenses_object = models.CharField( max_length=50, choices=COPORATE_CARD_EXPENSES_OBJECT_CHOICES, diff --git a/fyle_netsuite_api/urls.py b/fyle_netsuite_api/urls.py index b94fbc56..526b49ea 100644 --- a/fyle_netsuite_api/urls.py +++ b/fyle_netsuite_api/urls.py @@ -20,5 +20,6 @@ path('admin/', admin.site.urls), path('api/auth/', include('fyle_rest_auth.urls')), path('api/workspaces/', include('apps.workspaces.urls')), - path('api/user/', include('apps.users.urls')) + path('api/user/', include('apps.users.urls')), + path('api/v2/workspaces/', include('apps.workspaces.apis.urls')), ]