-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add error parser * chore: add parse error tests (#702) Co-authored-by: GitHub Actions <[email protected]> --------- Co-authored-by: GitHub Actions <[email protected]>
- Loading branch information
Showing
13 changed files
with
295 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import re | ||
|
||
from fyle_accounting_mappings.models import DestinationAttribute | ||
|
||
field_map = { | ||
'Accounts': {'type': 'ACCOUNT', 'article_link': None}, | ||
'Klasses': {'type': 'CLASS', 'article_link': None}, | ||
'Names': {'type': 'VENDOR', 'article_link': None}, | ||
'Depts': {'type': 'DEPARTMENT', 'article_link': None} | ||
} | ||
|
||
|
||
def error_matcher(error_msg): | ||
pattern = r'Invalid Reference Id : (\w+) element id (\d+) not found' | ||
|
||
match = re.search(pattern, error_msg) | ||
|
||
if match: | ||
# Extract the QBO element and its ID | ||
error_attribute, destination_id = match.groups() | ||
|
||
# Get the field info from the mapping | ||
field_info = field_map.get(error_attribute) | ||
|
||
if field_info: | ||
# Create a dictionary to store information about the error | ||
error_dict = { | ||
'attribute_type': field_info['type'], | ||
'destination_id': destination_id, | ||
'error_attribute': error_attribute, | ||
'article_link': field_info['article_link'] | ||
} | ||
|
||
return error_dict | ||
|
||
# If no match is found, return None | ||
return None | ||
|
||
|
||
def get_entity_values(error_dict, workspace_id): | ||
''' | ||
Get entity values from error dictionary | ||
:param error_dict: Error Dictionary containing information about the error | ||
:param workspace_id: ID of the workspace | ||
:return: Dictionary with 'destination_id' and 'value' if found, otherwise an empty dictionary | ||
''' | ||
# Fetch the destination attribute based on destination ID and attribute type | ||
destination_attribute = DestinationAttribute.objects.filter( | ||
destination_id=error_dict['destination_id'], | ||
attribute_type=error_dict['attribute_type'].upper(), | ||
workspace_id=workspace_id | ||
).first() | ||
|
||
# If the destination attribute is found, return a dictionary with 'destination_id' and 'value' | ||
if destination_attribute: | ||
return { | ||
'destination_id': error_dict['destination_id'], | ||
'value': destination_attribute.value, | ||
'error_attribute': error_dict['error_attribute'], | ||
'attribute_type': error_dict['attribute_type'] | ||
} | ||
|
||
# If no match is found or destination attribute is not active, return an empty dictionary | ||
return {} | ||
|
||
|
||
def replace_destination_id_with_values(input_string, replacement): | ||
''' | ||
Replace destination ID with corresponding values in the input string | ||
:param input_string: Original string containing destination ID placeholders | ||
:param replacement: Dictionary with 'destination_id' and 'value' to replace in the string | ||
:return: String with destination ID replaced by formatted 'destination_id => value' | ||
''' | ||
|
||
# Extract destination ID and value from the replacement dictionary | ||
destination_id = replacement['destination_id'] | ||
value = replacement['value'] | ||
error_attribute = replacement['error_attribute'] | ||
attribute_type = replacement['attribute_type'] | ||
|
||
# Create a formatted string in the form of 'destination_id => value' | ||
arrowed_string_value = f'{destination_id} => {value}' | ||
arrowed_string_attribute = f'{error_attribute} => {attribute_type}' | ||
|
||
# Replace occurrences of destination ID in the input string with the formatted string | ||
input_string = input_string.replace(destination_id, arrowed_string_value) | ||
input_string = input_string.replace(error_attribute, arrowed_string_attribute) | ||
|
||
# Return the modified input string | ||
return input_string |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Generated by Django 3.2.14 on 2024-11-27 07:30 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('tasks', '0011_error_repetition_count'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='error', | ||
name='article_link', | ||
field=models.TextField(blank=True, help_text='Article link', null=True), | ||
), | ||
migrations.AddField( | ||
model_name='error', | ||
name='attribute_type', | ||
field=models.CharField(blank=True, help_text='Error Attribute type', max_length=255, null=True), | ||
), | ||
migrations.AddField( | ||
model_name='error', | ||
name='is_parsed', | ||
field=models.BooleanField(default=False, help_text='Is parsed'), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from apps.quickbooks_online.errors.helpers import error_matcher, get_entity_values, replace_destination_id_with_values | ||
from apps.tasks.models import Error | ||
|
||
errors_count = Error.objects.filter(type='QBO_ERROR', is_resolved=False).count() | ||
print(errors_count) | ||
page_size = 200 | ||
count = 0 | ||
for offset in range(0, errors_count, page_size): | ||
limit = offset + page_size | ||
paginated_errors = Error.objects.filter(type='QBO_ERROR', is_resolved=False).order_by('id')[offset:limit] | ||
for error in paginated_errors: | ||
error_dict = error_matcher(error.error_detail) | ||
if error_dict: | ||
error_entity_values = get_entity_values(error_dict, error.workspace_id) | ||
if error_entity_values: | ||
error_msg = replace_destination_id_with_values(error.error_detail, error_entity_values) | ||
error.is_parsed = True | ||
error.article_link = error_dict['article_link'] | ||
error.attribute_type = error_dict['attribute_type'] | ||
error.error_detail = error_msg | ||
error.save() | ||
count += 1 | ||
|
||
print(count) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.