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

added field export_url in expense group and util to generate URL #457

Merged
merged 9 commits into from
Nov 29, 2023
18 changes: 18 additions & 0 deletions apps/fyle/migrations/0027_expensegroup_employee_name.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.1.14 on 2023-11-20 10:48

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('fyle', '0026_auto_20231025_0913'),
]

operations = [
migrations.AddField(
model_name='expensegroup',
name='employee_name',
field=models.CharField(help_text='Expense Group Employee Name', max_length=100, null=True),
),
]
18 changes: 18 additions & 0 deletions apps/fyle/migrations/0028_expensegroup_export_url.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.1.14 on 2023-11-22 10:11

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('fyle', '0027_expensegroup_employee_name'),
]

operations = [
migrations.AddField(
model_name='expensegroup',
name='export_url',
field=models.CharField(help_text='Netsuite URL for the exported expenses', max_length=255, null=True),
),
]
9 changes: 8 additions & 1 deletion apps/fyle/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,10 @@ class ExpenseGroup(models.Model):
help_text='To which workspace this expense group belongs to')
fund_source = models.CharField(max_length=255, help_text='Expense fund source')
expenses = models.ManyToManyField(Expense, help_text="Expenses under this Expense Group")
employee_name = models.CharField(max_length=100, help_text='Expense Group Employee Name', null=True)
description = JSONField(max_length=255, help_text='Description', null=True)
response_logs = JSONField(help_text='Reponse log of the export', null=True)
export_url = models.CharField(max_length=255, help_text='Netsuite URL for the exported expenses', null=True)
created_at = models.DateTimeField(auto_now_add=True, help_text='Created at')
exported_at = models.DateTimeField(help_text='Exported at', null=True)
updated_at = models.DateTimeField(auto_now=True, help_text='Updated at')
Expand Down Expand Up @@ -392,6 +394,10 @@ def create_expense_groups_by_report_id_fund_source(expense_objects: List[Expense
if expense_group_settings.ccc_export_date_type == 'last_spent_at':
expense_group['last_spent_at'] = Expense.objects.filter(
id__in=expense_group['expense_ids']).order_by('-spent_at').first().spent_at

employee_name = Expense.objects.filter(
id__in=expense_group['expense_ids']
).first().employee_name

expense_ids = expense_group['expense_ids']
expense_group.pop('total')
Expand All @@ -407,7 +413,8 @@ def create_expense_groups_by_report_id_fund_source(expense_objects: List[Expense
expense_group_object = ExpenseGroup.objects.create(
workspace_id=workspace_id,
fund_source=expense_group['fund_source'],
description=expense_group
description=expense_group,
employee_name=employee_name
)

expense_group_object.expenses.add(*expense_ids)
Expand Down
15 changes: 15 additions & 0 deletions apps/netsuite/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from django.utils.module_loading import import_string
from django_q.models import Schedule
from django_q.tasks import Chain, async_task
from fyle_netsuite_api.utils import generate_netsuite_export_url

from netsuitesdk.internal.exceptions import NetSuiteRequestError
from netsuitesdk import NetSuiteRateLimitError, NetSuiteLoginError
Expand Down Expand Up @@ -71,6 +72,13 @@
}


def add_export_url(response_logs, ns_account_id, expense_group):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generate_export_url

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, remove this whole func, call generate_netsuite_export_url directly

try:
url = generate_netsuite_export_url(response_logs, ns_account_id)
expense_group.export_url = url
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return url from this func and assign value there

except Exception as exception:
logger.info({'error': exception})

def load_attachments(netsuite_connection: NetSuiteConnector, expense: Expense, expense_group: ExpenseGroup):
"""
Get attachments from Fyle
Expand Down Expand Up @@ -447,7 +455,11 @@ def create_bill(expense_group, task_log_id):

expense_group.exported_at = datetime.now()
expense_group.response_logs = created_bill

add_export_url(response_logs=created_bill, ns_account_id=netsuite_credentials.ns_account_id, expense_group=expense_group)

expense_group.save()


async_task(
'apps.netsuite.tasks.upload_attachments_and_update_export',
Expand Down Expand Up @@ -564,6 +576,7 @@ def create_credit_card_charge(expense_group, task_log_id):

expense_group.exported_at = datetime.now()
expense_group.response_logs = created_credit_card_charge
add_export_url(response_logs=created_credit_card_charge, ns_account_id=netsuite_credentials.ns_account_id, expense_group=expense_group)
expense_group.save()

except NetSuiteCredentials.DoesNotExist:
Expand Down Expand Up @@ -654,6 +667,7 @@ def create_expense_report(expense_group, task_log_id):

expense_group.exported_at = datetime.now()
expense_group.response_logs = created_expense_report
add_export_url(response_logs=created_expense_report, ns_account_id=netsuite_credentials.ns_account_id, expense_group=expense_group)
expense_group.save()

async_task(
Expand Down Expand Up @@ -749,6 +763,7 @@ def create_journal_entry(expense_group, task_log_id):

expense_group.exported_at = datetime.now()
expense_group.response_logs = created_journal_entry
add_export_url(response_logs=created_journal_entry, ns_account_id=netsuite_credentials.ns_account_id, expense_group=expense_group)
expense_group.save()

async_task(
Expand Down
19 changes: 19 additions & 0 deletions fyle_netsuite_api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,22 @@ def filter_queryset(self, queryset):
filter_kwargs = {self.lookup_field: lookup_value}
queryset = queryset.filter(**filter_kwargs)
return super().filter_queryset(queryset)


export_type_redirection = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

declare const at top, all caps variable.

'vendorBill': 'vendbill',
'expenseReport': 'exprept',
'journalEntry': 'journal',
'chargeCard': 'cardchrg',
'chargeCardRefund': 'cardrfnd'
}

def generate_netsuite_export_url(response_logs, ns_account_id):

if response_logs:
export_type = response_logs['type'] if response_logs['type'] else 'chargeCard'
internal_id = response_logs['internalId']
redirection = export_type_redirection[export_type]
url = f'https://{ns_account_id}.app.netsuite.com/app/accounting/transactions/${redirection}.nl?id={internal_id}'
return url
return None
16 changes: 16 additions & 0 deletions scripts/python/update-export-url.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from apps.fyle.models import ExpenseGroup
from apps.workspaces.models import NetSuiteCredentials
from fyle_netsuite_api.utils import generate_netsuite_export_url


expense_groups = ExpenseGroup.objects.all()

for expense_group in expense_groups:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's iterate through workspaces (prod only - exclude workspaces that has name like test / fyle / sandbox). Iterate through workspace and filter expense groups that has response logs != null and do it in batches. https://github.com/fylein/fyle-integration-scripts/blob/master/qbo/batched-fill.py check this out on how to do it in batches

try:
netsuite_cred = NetSuiteCredentials.objects.get(workspace_id=expense_group.workspace_id)
url = generate_netsuite_export_url(response_logs=expense_group.response_logs, ns_account_id=netsuite_cred.ns_account_id)
expense_group.export_url = url
expense_group.save()
print('Export URl updated for expense group id {}'.format(expense_group.id))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove loggers

except Exception as exception:
print('Something went wrong during updating export_url for workspace_id {}'.format(expense_group.workspace_id))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add valid exceptions here

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
rollback;
begin;

with ws as (
select expense_attributes.detail->>'full_name' as expense_attributes_full_name,
expense_attributes.workspace_id as expense_attributes_workspace_id,
expense_attributes.value as expense_attribute_email
from expense_groups
inner join expense_attributes on expense_attributes.value = expense_groups.description->>'employee_email'
where expense_groups.workspace_id = expense_attributes.workspace_id
)

update expense_groups
set employee_name = ws.expense_attributes_full_name
from ws
where expense_groups.description->>'employee_email' = ws.expense_attribute_email;


-- Run this in after running the above query.
with ex as (
select expense_groups.employee_name as employee_name
from expense_groups
inner join expense_groups_expenses on expense_groups.id = expense_groups_expenses.expensegroup_id
inner join expenses on expense_groups_expenses.expense_id = expenses.id
)

update expenses
set employee_name = ex.employee_name
from ex;
Loading
Loading