-
Notifications
You must be signed in to change notification settings - Fork 3
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
feat: support split expense grouping #681
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Generated by Django 3.2.14 on 2024-11-18 15:00 | ||
|
||
import apps.fyle.models | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('fyle', '0034_expense_is_posted_at_null'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='expense', | ||
name='bank_transaction_id', | ||
field=models.CharField(blank=True, help_text='Bank Transaction ID', max_length=255, null=True), | ||
), | ||
migrations.AddField( | ||
model_name='expensegroupsettings', | ||
name='split_expense_grouping', | ||
field=models.CharField(choices=[('SINGLE_LINE_ITEM', 'SINGLE_LINE_ITEM'), ('MULTIPLE_LINE_ITEM', 'MULTIPLE_LINE_ITEM')], default=apps.fyle.models.get_default_split_expense_grouping, help_text='specify line items for split expenses grouping', max_length=100), | ||
), | ||
] |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -1581,51 +1581,50 @@ def get_bill(self, internal_id): | |||||||||||||
return bill | ||||||||||||||
|
||||||||||||||
def construct_credit_card_charge_lineitems( | ||||||||||||||
self, credit_card_charge_lineitem: CreditCardChargeLineItem, general_mapping: GeneralMapping, | ||||||||||||||
self, credit_card_charge_lineitems: List[CreditCardChargeLineItem], general_mapping: GeneralMapping, | ||||||||||||||
attachment_links: Dict, cluster_domain: str, org_id: str) -> List[Dict]: | ||||||||||||||
""" | ||||||||||||||
Create credit_card_charge line items | ||||||||||||||
:return: constructed line items | ||||||||||||||
""" | ||||||||||||||
line = credit_card_charge_lineitem | ||||||||||||||
|
||||||||||||||
lines = [] | ||||||||||||||
|
||||||||||||||
expense = Expense.objects.get(pk=line.expense_id) | ||||||||||||||
|
||||||||||||||
netsuite_custom_segments = self.prepare_custom_segments(line.netsuite_custom_segments, attachment_links, expense, org_id) | ||||||||||||||
|
||||||||||||||
base_line = { | ||||||||||||||
'account': {'internalId': line.account_id}, | ||||||||||||||
'amount': line.amount, | ||||||||||||||
'memo': line.memo, | ||||||||||||||
'grossAmt': line.amount, | ||||||||||||||
'department': {'internalId': line.department_id}, | ||||||||||||||
'class': {'internalId': line.class_id}, | ||||||||||||||
'location': {'internalId': line.location_id}, | ||||||||||||||
'customer': {'internalId': line.customer_id}, | ||||||||||||||
'customFieldList': netsuite_custom_segments, | ||||||||||||||
'isBillable': line.billable, | ||||||||||||||
'taxAmount': None, | ||||||||||||||
'taxCode': { | ||||||||||||||
'externalId': None, | ||||||||||||||
'internalId': None, | ||||||||||||||
'name': None, | ||||||||||||||
'type': 'taxGroup' | ||||||||||||||
}, | ||||||||||||||
} | ||||||||||||||
for line in credit_card_charge_lineitems: | ||||||||||||||
expense = Expense.objects.get(pk=line.expense_id) | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add Error Handling When Retrieving The code retrieves the Apply this diff to handle the exception: +from django.core.exceptions import ObjectDoesNotExist
...
- expense = Expense.objects.get(pk=line.expense_id)
+ try:
+ expense = Expense.objects.get(pk=line.expense_id)
+ except Expense.DoesNotExist:
+ # Handle the missing expense, e.g., log an error or skip this line item
+ continue
|
||||||||||||||
|
||||||||||||||
# Handle cases where no tax is applied first | ||||||||||||||
if line.tax_item_id is None or line.tax_amount is None: | ||||||||||||||
lines.append(base_line) | ||||||||||||||
else: | ||||||||||||||
lines += self.handle_taxed_line_items(base_line, line, expense.workspace_id, 'CREDIT_CARD_CHARGE', general_mapping) | ||||||||||||||
netsuite_custom_segments = self.prepare_custom_segments(line.netsuite_custom_segments, attachment_links, expense, org_id) | ||||||||||||||
|
||||||||||||||
base_line = { | ||||||||||||||
'account': {'internalId': line.account_id}, | ||||||||||||||
'amount': line.amount, | ||||||||||||||
'memo': line.memo, | ||||||||||||||
'grossAmt': line.amount, | ||||||||||||||
'department': {'internalId': line.department_id}, | ||||||||||||||
'class': {'internalId': line.class_id}, | ||||||||||||||
'location': {'internalId': line.location_id}, | ||||||||||||||
'customer': {'internalId': line.customer_id}, | ||||||||||||||
'customFieldList': netsuite_custom_segments, | ||||||||||||||
'isBillable': line.billable, | ||||||||||||||
'taxAmount': None, | ||||||||||||||
'taxCode': { | ||||||||||||||
'externalId': None, | ||||||||||||||
'internalId': None, | ||||||||||||||
'name': None, | ||||||||||||||
'type': 'taxGroup' | ||||||||||||||
}, | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
# Handle cases where no tax is applied first | ||||||||||||||
if line.tax_item_id is None or line.tax_amount is None: | ||||||||||||||
lines.append(base_line) | ||||||||||||||
else: | ||||||||||||||
lines += self.handle_taxed_line_items(base_line, line, expense.workspace_id, 'CREDIT_CARD_CHARGE', general_mapping) | ||||||||||||||
|
||||||||||||||
return lines | ||||||||||||||
|
||||||||||||||
def __construct_credit_card_charge( | ||||||||||||||
self, credit_card_charge: CreditCardCharge, | ||||||||||||||
credit_card_charge_lineitem: CreditCardChargeLineItem, general_mapping: GeneralMapping, attachment_links: Dict) -> Dict: | ||||||||||||||
credit_card_charge_lineitems: List[CreditCardChargeLineItem], general_mapping: GeneralMapping, attachment_links: Dict) -> Dict: | ||||||||||||||
""" | ||||||||||||||
Create a credit_card_charge | ||||||||||||||
:return: constructed credit_card_charge | ||||||||||||||
|
@@ -1664,15 +1663,15 @@ def __construct_credit_card_charge( | |||||||||||||
'memo': credit_card_charge.memo, | ||||||||||||||
'tranid': credit_card_charge.reference_number, | ||||||||||||||
'expenses': self.construct_credit_card_charge_lineitems( | ||||||||||||||
credit_card_charge_lineitem, general_mapping, attachment_links, cluster_domain, org_id | ||||||||||||||
credit_card_charge_lineitems, general_mapping, attachment_links, cluster_domain, org_id | ||||||||||||||
), | ||||||||||||||
'externalId': credit_card_charge.external_id | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
return credit_card_charge_payload | ||||||||||||||
|
||||||||||||||
def post_credit_card_charge(self, credit_card_charge: CreditCardCharge, | ||||||||||||||
credit_card_charge_lineitem: CreditCardChargeLineItem, general_mapping: GeneralMapping, attachment_links: Dict, | ||||||||||||||
credit_card_charge_lineitems: List[CreditCardChargeLineItem], general_mapping: GeneralMapping, attachment_links: Dict, | ||||||||||||||
refund: bool): | ||||||||||||||
""" | ||||||||||||||
Post vendor credit_card_charges to NetSuite | ||||||||||||||
|
@@ -1694,12 +1693,15 @@ def post_credit_card_charge(self, credit_card_charge: CreditCardCharge, | |||||||||||||
f"script=customscript_cc_charge_fyle&deploy=customdeploy_cc_charge_fyle" | ||||||||||||||
|
||||||||||||||
if refund: | ||||||||||||||
credit_card_charge_lineitem.amount = abs(credit_card_charge_lineitem.amount) | ||||||||||||||
for credit_card_charge_lineitem in credit_card_charge_lineitems: | ||||||||||||||
credit_card_charge_lineitem.amount = abs(credit_card_charge_lineitem.amount) | ||||||||||||||
credit_card_charge_lineitem.save() | ||||||||||||||
|
||||||||||||||
Comment on lines
+1696
to
+1699
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Avoid Modifying and Saving Line Items Within Refund Logic Modifying and saving Apply this diff: -for credit_card_charge_lineitem in credit_card_charge_lineitems:
- credit_card_charge_lineitem.amount = abs(credit_card_charge_lineitem.amount)
- credit_card_charge_lineitem.save()
+for line_item in credit_card_charge_lineitems:
+ line_item.amount = abs(line_item.amount)
+ # Avoid saving changes to the database to prevent side effects Alternatively, create a copy of the line items list and modify the copy to ensure the original data remains unchanged. 📝 Committable suggestion
Suggested change
|
||||||||||||||
url = f"https://{account.lower()}.restlets.api.netsuite.com/app/site/hosting/restlet.nl?" \ | ||||||||||||||
f"script=customscript_cc_refund_fyle&deploy=customdeploy_cc_refund_fyle" | ||||||||||||||
f"script=customscript_cc_refund_fyle&deploy=customdeploy_cc_refund_fyle" | ||||||||||||||
|
||||||||||||||
credit_card_charges_payload = self.__construct_credit_card_charge( | ||||||||||||||
credit_card_charge, credit_card_charge_lineitem, general_mapping, attachment_links) | ||||||||||||||
credit_card_charge, credit_card_charge_lineitems, general_mapping, attachment_links) | ||||||||||||||
|
||||||||||||||
logger.info("| Payload for Credit Card Charge creation | Content: {{WORKSPACE_ID: {} EXPENSE_GROUP_ID: {} CREDIT_CARD_CHARGE_PAYLOAD: {}}}".format(self.workspace_id, credit_card_charge.expense_group.id, credit_card_charges_payload)) | ||||||||||||||
|
||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle potential
KeyError
when accessingexpense['bank_transaction_id']
Accessing
expense['bank_transaction_id']
without checking may raise aKeyError
if'bank_transaction_id'
is missing in theexpense
dictionary. Consider usingexpense.get('bank_transaction_id')
to prevent possible exceptions.Apply this diff to fix the issue:
📝 Committable suggestion