Skip to content

Commit

Permalink
V2 Export setting api (#433)
Browse files Browse the repository at this point in the history
* onboarding state implementation

* tests migrations

* added onboarding state

* changed comment

* added subsidiary state to onboarding state

* changed script to add subsidiary state and fixed some bug

* bug fix

* state change on connection and subsidiary change

* map employees v2 api

* map_employees typos

* bug fix

* export setting changes

* export settings V2 api

* added test for export settings api

* resolved comments

---------

Co-authored-by: Ashutosh619-sudo <[email protected]>
Co-authored-by: Nilesh Pant <[email protected]>
  • Loading branch information
3 people authored Oct 26, 2023
1 parent 16509b3 commit 63102f8
Show file tree
Hide file tree
Showing 13 changed files with 503 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,4 @@ cache.db-journal
test_scripts/
fyle_accounting_mappings/
fyle_integrations_platform_connector/
fyle/
./fyle
20 changes: 20 additions & 0 deletions apps/fyle/migrations/0026_auto_20231025_0913.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 3.1.14 on 2023-10-25 09:13

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('workspaces', '0035_auto_20231019_1025'),
('fyle', '0025_auto_20230622_0516'),
]

operations = [
migrations.AlterField(
model_name='expensegroupsettings',
name='workspace',
field=models.OneToOneField(help_text='To which workspace this expense group setting belongs to', on_delete=django.db.models.deletion.PROTECT, related_name='expense_group_settings', to='workspaces.workspace'),
),
]
3 changes: 2 additions & 1 deletion apps/fyle/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ class ExpenseGroupSettings(models.Model):
ccc_export_date_type = models.CharField(max_length=100, default='current_date', help_text='CCC Export Date')
import_card_credits = models.BooleanField(help_text='Import Card Credits', default=False)
workspace = models.OneToOneField(
Workspace, on_delete=models.PROTECT, help_text='To which workspace this expense group setting belongs to'
Workspace, on_delete=models.PROTECT, help_text='To which workspace this expense group setting belongs to',
related_name = 'expense_group_settings'
)
created_at = models.DateTimeField(auto_now_add=True, help_text='Created at')
updated_at = models.DateTimeField(auto_now=True, help_text='Updated at')
Expand Down
20 changes: 20 additions & 0 deletions apps/mappings/migrations/0010_auto_20231025_0915.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 3.1.14 on 2023-10-25 09:15

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('workspaces', '0035_auto_20231019_1025'),
('mappings', '0009_auto_20211022_0702'),
]

operations = [
migrations.AlterField(
model_name='generalmapping',
name='workspace',
field=models.OneToOneField(help_text='Reference to Workspace model', on_delete=django.db.models.deletion.PROTECT, related_name='general_mappings', to='workspaces.workspace'),
),
]
2 changes: 1 addition & 1 deletion apps/mappings/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class GeneralMapping(models.Model):
vendor_payment_account_name = models.CharField(max_length=255, help_text='VendorPayment Account name', null=True)
default_ccc_vendor_id = models.CharField(max_length=255, help_text='Default CCC Vendor ID', null=True)
default_ccc_vendor_name = models.CharField(max_length=255, help_text='Default CCC Vendor Name', null=True)
workspace = models.OneToOneField(Workspace, on_delete=models.PROTECT, help_text='Reference to Workspace model')
workspace = models.OneToOneField(Workspace, on_delete=models.PROTECT, help_text='Reference to Workspace model', related_name='general_mappings')
created_at = models.DateTimeField(auto_now_add=True, help_text='Created at datetime')
updated_at = models.DateTimeField(auto_now=True, help_text='Updated at datetime')

Expand Down
Empty file.
173 changes: 173 additions & 0 deletions apps/workspaces/apis/export_settings/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
from apps.fyle.models import ExpenseGroupSettings
from apps.mappings.models import GeneralMapping
from apps.workspaces.models import Configuration, Workspace
from rest_framework import serializers

class ReadWriteSerializerMethodField(serializers.SerializerMethodField):
"""
Serializer Method Field to Read and Write from values
Inherits serializers.SerializerMethodField
"""

def __init__(self, method_name=None, **kwargs):
self.method_name = method_name
kwargs['source'] = '*'
super(serializers.SerializerMethodField, self).__init__(**kwargs)

def to_internal_value(self, data):
return {
self.field_name: data
}

class ConfigurationSerializer(serializers.ModelSerializer):

class Meta:
model = Configuration
fields = [
'reimbursable_expenses_object',
'corporate_credit_card_expenses_object',
'is_simplify_report_closure_enabled',
]

read_only_fields = ['is_simplify_report_closure_enabled']

class GeneralMappingsSerializer(serializers.ModelSerializer):
reimbursable_account = ReadWriteSerializerMethodField()
default_ccc_account = ReadWriteSerializerMethodField()
accounts_payable = ReadWriteSerializerMethodField()
default_ccc_vendor = ReadWriteSerializerMethodField()

class Meta:
model = GeneralMapping
fields = [
'reimbursable_account',
'default_ccc_account',
'accounts_payable',
'default_ccc_vendor',
]

def get_reimbursable_account(self, instance: GeneralMapping):
return {
'id': instance.reimbursable_account_id,
'name': instance.reimbursable_account_name
}

def get_default_ccc_account(self, instance: GeneralMapping):
return {
'id': instance.default_ccc_account_id,
'name': instance.default_ccc_account_name
}

def get_accounts_payable(self, instance: GeneralMapping):
return {
'id': instance.accounts_payable_id,
'name': instance.accounts_payable_name
}

def get_default_ccc_vendor(self, instance: GeneralMapping):
return {
'id': instance.default_ccc_vendor_id,
'name': instance.default_ccc_vendor_name
}

class ExpenseGroupSettingsSerializer(serializers.ModelSerializer):
reimbursable_expense_group_fields = serializers.ListField(allow_null=True, required=False)
reimbursable_export_date_type = serializers.CharField(allow_null=True, allow_blank=True, required=False)
expense_state = serializers.CharField(allow_null=True, allow_blank=True, required=False)
corporate_credit_card_expense_group_fields = serializers.ListField(allow_null=True, required=False)
ccc_export_date_type = serializers.CharField(allow_null=True, allow_blank=True, required=False)
ccc_expense_state = serializers.CharField(allow_null=True, allow_blank=True, required=False)

class Meta:
model = ExpenseGroupSettings
fields = [
'reimbursable_expense_group_fields',
'reimbursable_export_date_type',
'expense_state',
'corporate_credit_card_expense_group_fields',
'ccc_export_date_type',
'ccc_expense_state'
]


class ExportSettingsSerializer(serializers.ModelSerializer):
expense_group_settings = ExpenseGroupSettingsSerializer()
configuration = ConfigurationSerializer()
general_mappings = GeneralMappingsSerializer()
workspace_id = serializers.SerializerMethodField()

class Meta:
model = Workspace
fields = [
'expense_group_settings',
'configuration',
'general_mappings',
'workspace_id'
]
read_only_fields = ['workspace_id']


def get_workspace_id(self, instance):
return instance.id

def update(self, instance: Workspace, validated_data):

configurations = validated_data.pop('configuration')
expense_group_settings = validated_data.pop('expense_group_settings')
general_mappings = validated_data.pop('general_mappings')
workspace_id = instance.id

Configuration.objects.update_or_create(
workspace_id=workspace_id,
defaults={
'reimbursable_expenses_object': configurations['reimbursable_expenses_object'],
'corporate_credit_card_expenses_object': configurations['corporate_credit_card_expenses_object'],
}
)

if not expense_group_settings['reimbursable_expense_group_fields']:
expense_group_settings['reimbursable_expense_group_fields'] = ['employee_email', 'report_id', 'fund_source', 'claim_number']

if not expense_group_settings['corporate_credit_card_expense_group_fields']:
expense_group_settings['corporate_credit_card_expense_group_fields'] = ['employee_email', 'report_id', 'fund_source', 'claim_number']

if not expense_group_settings['reimbursable_export_date_type']:
expense_group_settings['reimbursable_export_date_type'] = 'current_date'

if not expense_group_settings['ccc_export_date_type']:
expense_group_settings['ccc_export_date_type'] = 'current_date'

ExpenseGroupSettings.update_expense_group_settings(expense_group_settings, workspace_id=workspace_id)

GeneralMapping.objects.update_or_create(
workspace = instance,
defaults={
'reimbursable_account_id': general_mappings['reimbursable_account']['id'],
'reimbursable_account_name': general_mappings['reimbursable_account']['name'],
'default_ccc_account_id': general_mappings['default_ccc_account']['id'],
'default_ccc_account_name': general_mappings['default_ccc_account']['name'],
'accounts_payable_id': general_mappings['accounts_payable']['id'],
'accounts_payable_name': general_mappings['accounts_payable']['name'],
'default_ccc_vendor_id': general_mappings['default_ccc_vendor']['id'],
'default_ccc_vendor_name': general_mappings['default_ccc_vendor']['name']
}
)

if instance.onboarding_state == 'EXPORT_SETTINGS':
instance.onboarding_state = 'IMPORT_SETTINGS'
instance.save()

return instance

def validate(self, data):

if not data.get('expense_group_settings'):
raise serializers.ValidationError('Expense group settings are required')

if not data.get('configuration'):
raise serializers.ValidationError('Configurations settings are required')

if not data.get('general_mappings'):
raise serializers.ValidationError('General mappings are required')

return data
12 changes: 12 additions & 0 deletions apps/workspaces/apis/export_settings/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from rest_framework import generics

from apps.workspaces.models import Workspace

from apps.workspaces.apis.export_settings.serializers import ExportSettingsSerializer


class ExportSettingsView(generics.RetrieveUpdateAPIView):
serializer_class = ExportSettingsSerializer

def get_object(self):
return Workspace.objects.filter(id=self.kwargs['workspace_id']).first()
4 changes: 3 additions & 1 deletion apps/workspaces/apis/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from django.urls import path

from apps.workspaces.apis.map_employees.views import MapEmployeesView
from apps.workspaces.apis.export_settings.views import ExportSettingsView


urlpatterns = [
path('<int:workspace_id>/map_employees/', MapEmployeesView.as_view()),
path('<int:workspace_id>/map_employees/', MapEmployeesView.as_view(), name='map-employees'),
path('<int:workspace_id>/export_settings/', ExportSettingsView.as_view(), name='export-settings'),
]
Empty file.
Empty file.
Loading

0 comments on commit 63102f8

Please sign in to comment.