Skip to content

Commit

Permalink
feat: Add extensive logger and limits (#167)
Browse files Browse the repository at this point in the history
* feat: Add extensive logger and limits

* test fixed

* added settings for logger

* change to info

* bump up version

* added test
  • Loading branch information
Ashutosh619-sudo committed Oct 16, 2024
1 parent 7a67ff4 commit acd68e5
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 4 deletions.
36 changes: 36 additions & 0 deletions apps/business_central/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import base64
import logging
from typing import Dict, List
from datetime import datetime
from django.utils import timezone

from dynamics.core.client import Dynamics
from fyle_accounting_mappings.models import DestinationAttribute
Expand All @@ -11,6 +13,12 @@
logger = logging.getLogger(__name__)
logger.level = logging.INFO

SYNC_UPPER_LIMIT = {
'accounts': 2000,
'vendors': 10000,
'locations': 1000
}


class BusinessCentralConnector:
"""
Expand Down Expand Up @@ -58,6 +66,22 @@ def _create_destination_attribute(self, attribute_type, display_name, value, des
'detail': detail
}

def is_sync_allowed(self, attribute_type: str, attribute_count: int):
"""
Checks if the sync is allowed
Returns:
bool: True
"""
if attribute_count > SYNC_UPPER_LIMIT[attribute_type]:
workspace_created_at = Workspace.objects.get(id=self.workspace_id).created_at
if workspace_created_at > timezone.make_aware(datetime(2024, 10, 1), timezone.get_current_timezone()):
return False
else:
return True

return True

def _sync_data(self, data, attribute_type, display_name, workspace_id, field_names):
"""
Synchronize data from MS Dynamics SDK to your application
Expand Down Expand Up @@ -111,6 +135,10 @@ def sync_accounts(self):
"""
Synchronize accounts from MS Dynamics SDK to your application
"""
attribute_count = self.connection.accounts.count()
if not self.is_sync_allowed(attribute_type = 'accounts', attribute_count=attribute_count):
logger.info('Skipping sync of accounts for workspace %s as it has %s counts which is over the limit', self.workspace_id, attribute_count)
return
field_names = ['category', 'subCategory', 'accountType', 'directPosting', 'lastModifiedDateTime']

accounts = self.connection.accounts.get_all()
Expand All @@ -121,6 +149,10 @@ def sync_vendors(self):
"""
Synchronize vendors from MS Dynamics SDK to your application
"""
attribute_count = self.connection.vendors.count()
if not self.is_sync_allowed(attribute_type = 'vendors', attribute_count=attribute_count):
logger.info('Skipping sync of vendors for workspace %s as it has %s counts which is over the limit', self.workspace_id, attribute_count)
return
field_names = ['email', 'currencyId', 'currencyCode', 'lastModifiedDateTime']

vendors = self.connection.vendors.get_all()
Expand All @@ -141,6 +173,10 @@ def sync_locations(self):
"""
Synchronize locations from MS Dynamics SDK to your application
"""
attribute_count = self.connection.locations.count()
if not self.is_sync_allowed(attribute_type = 'locations', attribute_count = attribute_count):
logger.info('Skipping sync of locations for workspace %s as it has %s counts which is over the limit', self.workspace_id, attribute_count)
return
field_names = ['code', 'city', 'country']

locations = self.connection.locations.get_all()
Expand Down
17 changes: 15 additions & 2 deletions ms_business_central_api/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,11 @@
'requests': {
'format': 'request {levelname} %s {asctime} {message}' % SERVICE_NAME,
'style': '{'
}
},
"standard": {
"format": "{levelname} %s {asctime} {name} {message}" % SERVICE_NAME,
"style": "{",
},
},
'handlers': {
'debug_logs': {
Expand All @@ -141,6 +145,10 @@
'stream': sys.stdout,
'formatter': 'requests'
},
"console": {
"class": "logging.StreamHandler",
"formatter": "standard",
},
},
'loggers': {
'django': {
Expand Down Expand Up @@ -173,7 +181,12 @@
'handlers': ['request_logs'],
'level': 'INFO',
'propagate': False
}
},
"dynamics.apis.api_base": {
"handlers": ["console"],
"level": "INFO",
"propagate": True
},
}
}

Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ gevent==23.9.1
gunicorn==20.1.0

# Platform SDK
fyle==0.37.0
fyle==0.37.2

# Business central sdk
ms-dynamics-business-central-sdk==1.4.2
ms-dynamics-business-central-sdk==1.5.2

# Reusable Fyle Packages
fyle-rest-auth==1.7.2
Expand Down
52 changes: 52 additions & 0 deletions tests/test_business_central/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
from apps.workspaces.models import Workspace
from datetime import datetime
from fyle_accounting_mappings.models import DestinationAttribute, Mapping, CategoryMapping


def test_post_attachments(
db,
mocker,
Expand Down Expand Up @@ -143,3 +148,50 @@ def test_bulk_post_journal_lineitems(
assert len(response) == 2
assert response[0]['id'] == 'Journal_Line_Item_Id'
assert response[1]['id'] == 'Journal_Line_Item_Id_2'


def test_skip_sync_attributes(mocker, db, create_business_central_connection):

today = datetime.today()
Workspace.objects.filter(id=1).update(created_at=today)
business_central_connection = create_business_central_connection

Mapping.objects.filter(workspace_id=1).delete()
CategoryMapping.objects.filter(workspace_id=1).delete()

DestinationAttribute.objects.filter(workspace_id=1, attribute_type='VENDOR').delete()

mocker.patch.object(
business_central_connection.connection.vendors,
'count',
return_value=10001
)

business_central_connection.sync_vendors()

vendors = DestinationAttribute.objects.filter(attribute_type='VENDOR', workspace_id=1).count()
assert vendors == 0

DestinationAttribute.objects.filter(workspace_id=1, attribute_type='LOCATION').delete()
mocker.patch.object(
business_central_connection.connection.locations,
'count',
return_value=1001
)

business_central_connection.sync_locations()

locations = DestinationAttribute.objects.filter(attribute_type='LOCATION', workspace_id=1).count()
assert locations == 0

DestinationAttribute.objects.filter(workspace_id=1, attribute_type='ACCOUNT').delete()
mocker.patch.object(
business_central_connection.connection.accounts,
'count',
return_value=2001
)

business_central_connection.sync_accounts()

accounts = DestinationAttribute.objects.filter(attribute_type='ACCOUNT', workspace_id=1).count()
assert accounts == 0
4 changes: 4 additions & 0 deletions tests/test_mappings/test_imports/test_modules/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ def test_sync_destination_attributes(
"dynamics.apis.Accounts.get_all",
return_value=destination_attributes_data["get_account_destination_attributes"],
)
mocker.patch(
"dynamics.apis.Accounts.count",
return_value=5,
)

account_count = DestinationAttribute.objects.filter(
workspace_id=workspace_id, attribute_type="ACCOUNT"
Expand Down
12 changes: 12 additions & 0 deletions tests/test_mappings/test_imports/test_modules/test_categories.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ def test_sync_destination_attributes_categories(
"dynamics.apis.Accounts.get_all",
return_value=destination_attributes_data["get_account_destination_attributes"],
)
mocker.patch(
"dynamics.apis.Accounts.count",
return_value=5,
)

account_count = DestinationAttribute.objects.filter(
workspace_id=workspace_id, attribute_type="ACCOUNT"
Expand All @@ -36,6 +40,10 @@ def test_sync_destination_attributes_categories(
).count()
assert new_account_count == 2

mocker.patch(
"dynamics.apis.Locations.count",
return_value=5
)
mocker.patch(
"dynamics.apis.Locations.get_all",
return_value=destination_attributes_data[
Expand Down Expand Up @@ -132,6 +140,10 @@ def test_auto_create_destination_attributes(
"fyle_integrations_platform_connector.apis.Categories.post_bulk",
return_value=[],
)
mocker.patch(
"dynamics.apis.Accounts.count",
return_value=5
)
mocker.patch(
"dynamics.apis.Accounts.get_all",
return_value=destination_attributes_data[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ def test_auto_create_destination_attributes(
"fyle_integrations_platform_connector.apis.CostCenters.post_bulk",
return_value=[],
)
mocker.patch(
"dynamics.apis.Locations.count",
return_value=5,
)
mocker.patch(
"dynamics.apis.Locations.get_all",
return_value=data["get_location_destination_attributes_0"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ def test_auto_create_destination_attributes(
"fyle_integrations_platform_connector.apis.ExpenseCustomFields.post",
return_value=[],
)
mocker.patch(
"dynamics.apis.Locations.count",
return_value=5,
)
mocker.patch(
"dynamics.apis.Locations.get_all",
return_value=data["get_location_destination_attributes_2"],
Expand Down Expand Up @@ -139,6 +143,10 @@ def test_auto_create_destination_attributes(
"fyle_integrations_platform_connector.apis.ExpenseCustomFields.get_by_id",
return_value=data["create_new_auto_create_expense_custom_fields_get_by_id"],
)
mocker.patch(
"dynamics.apis.Locations.count",
return_value=5,
)
mocker.patch(
"dynamics.apis.Locations.get_all",
return_value=data["get_location_destination_attributes_3"],
Expand Down
12 changes: 12 additions & 0 deletions tests/test_mappings/test_imports/test_modules/test_merchants.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ def test_sync_destination_atrributes(
add_business_central_creds,
mocker,
):
mocker.patch(
"dynamics.apis.Vendors.count",
return_value=5,
)
mocker.patch(
"dynamics.apis.Vendors.get_all",
return_value=data["get_vendors_destination_attributes"],
Expand Down Expand Up @@ -107,6 +111,10 @@ def test_auto_create_destination_attributes(
mocker.patch(
"fyle_integrations_platform_connector.apis.Merchants.post", return_value=[]
)
mocker.patch(
"dynamics.apis.Vendors.count",
return_value=5,
)
mocker.patch(
"dynamics.apis.Vendors.get_all",
return_value=data["get_vendors_destination_attributes"],
Expand Down Expand Up @@ -151,6 +159,10 @@ def test_auto_create_destination_attributes(
mocker.patch(
"fyle_integrations_platform_connector.apis.Merchants.post", return_value=[]
)
mocker.patch(
"dynamics.apis.Vendors.count",
return_value=5,
)
mocker.patch(
"dynamics.apis.Vendors.get_all",
return_value=data["get_vendors_destination_attributes_subsequent_run"],
Expand Down

0 comments on commit acd68e5

Please sign in to comment.