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

Export setting api #8

Merged
merged 2 commits into from
Oct 31, 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
30 changes: 30 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Continuous Integration

on:
pull_request:
types: [assigned, opened, synchronize, reopened]

jobs:
pytest:
runs-on: ubuntu-latest
environment: CI Environment
steps:
- uses: actions/checkout@v2
- name: Bring up Services and Run Tests
run: |
docker-compose -f docker-compose-pipeline.yml build
docker-compose -f docker-compose-pipeline.yml up -d
docker-compose -f docker-compose-pipeline.yml exec -T api pytest tests/ --cov --junit-xml=test-reports/report.xml --cov-report=xml --cov-fail-under=70
echo "STATUS=$(cat pytest-coverage.txt | grep 'Required test' | awk '{ print $1 }')" >> $GITHUB_ENV
echo "FAILED=$(cat test-reports/report.xml | awk -F'=' '{print $5}' | awk -F' ' '{gsub(/"/, "", $1); print $1}')" >> $GITHUB_ENV
- name: Upload coverage reports to Codecov with GitHub Action
uses: codecov/codecov-action@v3
- name: Pytest coverage comment
uses: MishaKav/pytest-coverage-comment@main
if: ${{ always() && github.ref != 'refs/heads/master' }}
with:
create-new-comment: true
junitxml-path: ./test-reports/report.xml
- name: Evaluate Coverage
if: ${{ (env.STATUS == 'FAIL') || (env.FAILED > 0) }}
run: exit 1
95 changes: 94 additions & 1 deletion apps/workspaces/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
CustomDateTimeField,
StringOptionsField,
TextNotNullField,
StringNullField
StringNullField,
BooleanTrueField
)

User = get_user_model()
Expand Down Expand Up @@ -76,3 +77,95 @@ class FyleCredential(BaseModel):

class Meta:
db_table = 'fyle_credentials'


# Reimbursable Expense Choices
REIMBURSABLE_EXPENSE_EXPORT_TYPE_CHOICES = (
('PURCHASE_INVOICE', 'PURCHASE_INVOICE'),
('JOURNAL_ENTRY', 'JOURNAL_ENTRY')
)

REIMBURSABLE_EXPENSE_STATE_CHOICES = (
('PAYMENT_PROCESSING', 'PAYMENT_PROCESSING'),
('CLOSED', 'CLOSED')
)

REIMBURSABLE_EXPENSES_GROUPED_BY_CHOICES = (
('REPORT', 'report_id'),
('EXPENSE', 'expense_id')
)

REIMBURSABLE_EXPENSES_DATE_TYPE_CHOICES = (
('LAST_SPENT_AT', 'last_spent_at'),
('CREATED_AT', 'created_at'),
('SPENT_AT', 'spent_at')
)

# Credit Card Expense Choices
CREDIT_CARD_EXPENSE_EXPORT_TYPE_CHOICES = (
('JOURNAL_ENTRY', 'JOURNAL_ENTRY'),
)

CREDIT_CARD_EXPENSE_STATE_CHOICES = (
('APPROVED', 'APPROVED'),
('PAYMENT_PROCESSING', 'PAYMENT_PROCESSING'),
('PAID', 'PAID')
)

CREDIT_CARD_EXPENSES_GROUPED_BY_CHOICES = (
('REPORT', 'report_id'),
('EXPENSE', 'expense_id')
)

CREDIT_CARD_EXPENSES_DATE_TYPE_CHOICES = (
('LAST_SPENT_AT', 'last_spent_at'),
('POSTED_AT', 'posted_at'),
('CREATED_AT', 'created_at')
)


class ExportSetting(BaseModel):
"""
Table to store export settings
"""
# Reimbursable Expenses Export Settings
id = models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)
reimbursable_expenses_export_type = StringOptionsField(
choices=REIMBURSABLE_EXPENSE_EXPORT_TYPE_CHOICES,
)
default_bank_account_name = StringNullField(help_text='Bank account name')
default_back_account_id = StringNullField(help_text='Bank Account ID')
reimbursable_expense_state = StringOptionsField(
choices=REIMBURSABLE_EXPENSE_STATE_CHOICES
)
reimbursable_expense_date = StringOptionsField(
choices=REIMBURSABLE_EXPENSES_DATE_TYPE_CHOICES
)
reimbursable_expense_grouped_by = StringOptionsField(
choices=REIMBURSABLE_EXPENSES_GROUPED_BY_CHOICES
)
# Credit Card Expenses Export Settings
credit_card_expense_export_type = StringOptionsField(
choices=CREDIT_CARD_EXPENSE_EXPORT_TYPE_CHOICES
)
credit_card_expense_state = StringOptionsField(
choices=CREDIT_CARD_EXPENSE_STATE_CHOICES
)
default_reimbursable_account_name = StringNullField(help_text='Reimbursable account name')
default_reimbursable_account_id = StringNullField(help_text='Reimbursable Account ID')
default_ccc_credit_card_account_name = StringNullField(help_text='CCC Credit card account name')
default_ccc_credit_card_account_id = StringNullField(help_text='CCC Credit Card Account ID')
default_reimbursable_credit_card_account_name = StringNullField(help_text='Reimbursable Credit card account name')
default_reimbursable_credit_card_account_id = StringNullField(help_text='Reimbursable Credit card account name')
credit_card_expense_grouped_by = StringOptionsField(
choices=CREDIT_CARD_EXPENSES_GROUPED_BY_CHOICES
)
credit_card_expense_date = StringOptionsField(
choices=CREDIT_CARD_EXPENSES_DATE_TYPE_CHOICES
)
default_vendor_name = StringNullField(help_text='default Vendor Name')
default_vendor_id = StringNullField(help_text='default Vendor Id')
auto_map_employees = BooleanTrueField(help_text='Auto map employees')

class Meta:
db_table = 'export_settings'
35 changes: 34 additions & 1 deletion apps/workspaces/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
from fyle_rest_auth.helpers import get_fyle_admin
from fyle_rest_auth.models import AuthToken

from ms_business_central_api.utils import assert_valid
from apps.workspaces.models import (
Workspace,
FyleCredential
FyleCredential,
ExportSetting
)
from apps.users.models import User
from apps.fyle.helpers import get_cluster_domain
Expand Down Expand Up @@ -63,3 +65,34 @@ def create(self, validated_data):
)

return workspace


class ExportSettingsSerializer(serializers.ModelSerializer):
"""
Export Settings serializer
"""
class Meta:
model = ExportSetting
fields = '__all__'
read_only_fields = ('id', 'workspace', 'created_at', 'updated_at')

def create(self, validated_data):
"""
Create Export Settings
"""
assert_valid(validated_data, 'Body cannot be null')
workspace_id = self.context['request'].parser_context.get('kwargs').get('workspace_id')

export_settings, _ = ExportSetting.objects.update_or_create(
workspace_id=workspace_id,
defaults=validated_data
)

# Update workspace onboarding state
workspace = export_settings.workspace

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

return export_settings
2 changes: 2 additions & 0 deletions apps/workspaces/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
from apps.workspaces.views import (
ReadyView,
WorkspaceView,
ExportSettingView
)


workspace_app_paths = [
path('', WorkspaceView.as_view(), name='workspaces'),
path('ready/', ReadyView.as_view(), name='ready'),
path('<int:workspace_id>/export_settings/', ExportSettingView.as_view(), name='export-settings'),

]

Expand Down
16 changes: 14 additions & 2 deletions apps/workspaces/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@

from ms_business_central_api.utils import assert_valid
from apps.workspaces.models import (
Workspace
Workspace,
ExportSetting
)
from apps.workspaces.serializers import (
WorkspaceSerializer
WorkspaceSerializer,
ExportSettingsSerializer
)


Expand Down Expand Up @@ -68,3 +70,13 @@ def get(self, request, *args, **kwargs):
},
status=status.HTTP_200_OK
)


class ExportSettingView(generics.CreateAPIView, generics.RetrieveAPIView):
"""
Retrieve or Create Export Settings
"""
serializer_class = ExportSettingsSerializer
lookup_field = 'workspace_id'

queryset = ExportSetting.objects.all()
83 changes: 82 additions & 1 deletion tests/test_workspaces/test_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import pytest # noqa
from django.urls import reverse
from apps.workspaces.models import (
Workspace
Workspace,
ExportSetting
)


Expand Down Expand Up @@ -48,3 +49,83 @@ def test_get_of_workspace(api_client, test_connection):
assert response.status_code == 200
assert response.data['name'] == 'Fyle For MS Dynamics Demo'
assert response.data['org_id'] == 'orNoatdUnm1w'


def test_export_settings(api_client, test_connection):
'''
Test export settings
'''
url = reverse('workspaces')
api_client.credentials(HTTP_AUTHORIZATION='Bearer {}'.format(test_connection.access_token))
response = api_client.post(url)

workspace_id = response.data['id']

url = reverse('export-settings', kwargs={'workspace_id': workspace_id})

api_client.credentials(HTTP_AUTHORIZATION='Bearer {}'.format(test_connection.access_token))
response = api_client.post(url)
assert response.status_code == 400

payload = {
'reimbursable_expenses_export_type': 'PURCHASE_INVOICE',
'reimbursable_expense_state': 'PAYMENT_PROCESSING',
'reimbursable_expense_date': 'LAST_SPENT_AT',
'reimbursable_expense_grouped_by': 'EXPENSE',
'credit_card_expense_export_type': 'JOURNAL_ENTRY',
'credit_card_expense_state': 'PAID',
'credit_card_expense_grouped_by': 'EXPENSE',
'credit_card_expense_date': 'CREATED_AT',
'default_reimbursable_account_name': 'reimbursable account',
'default_reimbursable_account_id': '123',
'default_ccc_credit_card_account_name': 'CCC credit card account',
'default_ccc_credit_card_account_id': '123',
'default_reimbursable_credit_card_account_name': 'reimbursable credit card account',
'default_reimbursable_credit_card_account_id': '342',
'default_vendor_name': 'Nilesh',
'default_vendor_id': '123',
'default_back_account_id': '123',
'default_bank_account_name': 'Bank account'
}

response = api_client.post(url, payload)

export_settings = ExportSetting.objects.filter(workspace_id=workspace_id).first()

assert response.status_code == 201
assert export_settings.reimbursable_expenses_export_type == 'PURCHASE_INVOICE'
assert export_settings.reimbursable_expense_state == 'PAYMENT_PROCESSING'
assert export_settings.reimbursable_expense_date == 'LAST_SPENT_AT'
assert export_settings.reimbursable_expense_grouped_by == 'EXPENSE'
assert export_settings.credit_card_expense_export_type == 'JOURNAL_ENTRY'
assert export_settings.credit_card_expense_state == 'PAID'
assert export_settings.credit_card_expense_grouped_by == 'EXPENSE'
assert export_settings.credit_card_expense_date == 'CREATED_AT'
assert export_settings.default_reimbursable_account_name == 'reimbursable account'
assert export_settings.default_reimbursable_account_id == '123'
assert export_settings.default_ccc_credit_card_account_name == 'CCC credit card account'
assert export_settings.default_ccc_credit_card_account_id == '123'
assert export_settings.default_reimbursable_credit_card_account_name == 'reimbursable credit card account'
assert export_settings.default_reimbursable_credit_card_account_id == '342'
assert export_settings.default_vendor_name == 'Nilesh'
assert export_settings.default_vendor_id == '123'

response = api_client.get(url)

assert response.status_code == 200
assert export_settings.reimbursable_expenses_export_type == 'PURCHASE_INVOICE'
assert export_settings.reimbursable_expense_state == 'PAYMENT_PROCESSING'
assert export_settings.reimbursable_expense_date == 'LAST_SPENT_AT'
assert export_settings.reimbursable_expense_grouped_by == 'EXPENSE'
assert export_settings.credit_card_expense_export_type == 'JOURNAL_ENTRY'
assert export_settings.credit_card_expense_state == 'PAID'
assert export_settings.credit_card_expense_grouped_by == 'EXPENSE'
assert export_settings.credit_card_expense_date == 'CREATED_AT'
assert export_settings.default_reimbursable_account_name == 'reimbursable account'
assert export_settings.default_reimbursable_account_id == '123'
assert export_settings.default_ccc_credit_card_account_name == 'CCC credit card account'
assert export_settings.default_ccc_credit_card_account_id == '123'
assert export_settings.default_reimbursable_credit_card_account_name == 'reimbursable credit card account'
assert export_settings.default_reimbursable_credit_card_account_id == '342'
assert export_settings.default_vendor_name == 'Nilesh'
assert export_settings.default_vendor_id == '123'
Loading