Skip to content

Commit

Permalink
Implementaion of sync method for fyle and bamboohr (#112)
Browse files Browse the repository at this point in the history
* Implementaion of sync method for fyle and bamboohr

* sync employees method added to platform connector

* implementation of sync fyle and bamboo hr

* removing api_token

* indent correction

* comment resolved

* minor bug fix

* better code

* Import sync department (#115)

* Syncing Department from Bamboohr to Fyle

* resolved commented code

* better optimized code

* comment resolved

* Employee and Approver Import (#116)

* Employee and Approver Import

* bug fix and comment resolved
  • Loading branch information
Ashutosh619-sudo authored Dec 26, 2023
1 parent 5762644 commit d9aa46f
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 66 deletions.
3 changes: 2 additions & 1 deletion admin_settings/tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
'apps.orgs',
'apps.travelperk',
'apps.gusto',
'apps.integrations'
'apps.integrations',
'apps.fyle_hrms_mappings',
]

MIDDLEWARE = [
Expand Down
30 changes: 30 additions & 0 deletions apps/fyle_hrms_mappings/migrations/0003_auto_20231221_1815.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 3.1.14 on 2023-12-21 18:15

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('orgs', '0004_auto_20230627_1133'),
('fyle_hrms_mappings', '0002_auto_20231221_1515'),
]

operations = [
migrations.AlterUniqueTogether(
name='destinationattribute',
unique_together={('destination_id', 'attribute_type', 'org')},
),
migrations.AlterUniqueTogether(
name='expenseattribute',
unique_together={('value', 'attribute_type', 'org')},
),
migrations.AlterModelTable(
name='destinationattribute',
table='destination_attributes',
),
migrations.AlterModelTable(
name='expenseattribute',
table='expense_attributes',
),
]
21 changes: 10 additions & 11 deletions apps/fyle_hrms_mappings/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ class DestinationAttribute(models.Model):
auto_created = models.BooleanField(default=False,
help_text='Indicates whether the field is auto created by the integration')

class Meta:
db_table = 'destination_attributes'
unique_together = ('destination_id', 'attribute_type', 'org')

@staticmethod
def create_or_update_destination_attribute(attribute: Dict, org_id):
"""
Expand All @@ -33,7 +37,6 @@ def create_or_update_destination_attribute(attribute: Dict, org_id):
org_id=org_id,
defaults={
'active': attribute['active'] if 'active' in attribute else None,
'display_name': attribute['display_name'],
'value': attribute['value'],
'detail': attribute['detail'] if 'detail' in attribute else None
}
Expand All @@ -42,14 +45,13 @@ def create_or_update_destination_attribute(attribute: Dict, org_id):

@staticmethod
def bulk_create_or_update_destination_attributes(
attributes: List[Dict], attribute_type: str, org_id: int, update: bool = False, display_name: str = None):
attributes: List[Dict], attribute_type: str, org_id: int, update: bool = False):
"""
Create Destination Attributes in bulk
:param update: Update Pre-existing records or not
:param attribute_type: Attribute type
:param attributes: attributes = [{
'attribute_type': Type of attribute,
'display_name': Display_name of attribute_field,
'value': Value of attribute,
'destination_id': Destination Id of the attribute,
'detail': Extra Details of the attribute
Expand All @@ -64,11 +66,9 @@ def bulk_create_or_update_destination_attributes(
'attribute_type': attribute_type,
'org_id': org_id
}
if display_name:
filters['display_name'] = display_name

existing_attributes = DestinationAttribute.objects.filter(**filters)\
.values('id', 'destination_id', 'detail', 'active')
.values('id', 'destination_id', 'value', 'detail', 'active')

existing_attribute_destination_ids = []

Expand All @@ -94,7 +94,6 @@ def bulk_create_or_update_destination_attributes(
attributes_to_be_created.append(
DestinationAttribute(
attribute_type=attribute_type,
display_name=attribute['display_name'],
value=attribute['value'],
destination_id=attribute['destination_id'],
detail=attribute['detail'] if 'detail' in attribute else None,
Expand Down Expand Up @@ -142,6 +141,9 @@ class ExpenseAttribute(models.Model):
auto_created = models.BooleanField(default=False,
help_text='Indicates whether the field is auto created by the integration')

class Meta:
db_table = 'expense_attributes'
unique_together = ('value', 'attribute_type', 'org')

@staticmethod
def create_or_update_expense_attribute(attribute: Dict, org_id):
Expand All @@ -155,7 +157,6 @@ def create_or_update_expense_attribute(attribute: Dict, org_id):
defaults={
'active': attribute['active'] if 'active' in attribute else None,
'source_id': attribute['source_id'],
'display_name': attribute['display_name'],
'detail': attribute['detail'] if 'detail' in attribute else None
}
)
Expand All @@ -170,7 +171,6 @@ def bulk_create_or_update_expense_attributes(
:param attribute_type: Attribute type
:param attributes: attributes = [{
'attribute_type': Type of attribute,
'display_name': Display_name of attribute_field,
'value': Value of attribute,
'source_id': Fyle Id of the attribute,
'detail': Extra Details of the attribute
Expand All @@ -182,7 +182,7 @@ def bulk_create_or_update_expense_attributes(

existing_attributes = ExpenseAttribute.objects.filter(
value__in=attribute_value_list, attribute_type=attribute_type,
org_id=org_id).values('id', 'detail', 'active')
org_id=org_id).values('id', 'detail', 'value', 'active')

existing_attribute_values = []

Expand All @@ -206,7 +206,6 @@ def bulk_create_or_update_expense_attributes(
attributes_to_be_created.append(
ExpenseAttribute(
attribute_type=attribute_type,
display_name=attribute['display_name'],
value=attribute['value'],
source_id=attribute['source_id'],
detail=attribute['detail'] if 'detail' in attribute else None,
Expand Down
49 changes: 48 additions & 1 deletion apps/users/helpers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from django.conf import settings
import json
from typing import Dict
from typing import Dict, List
import requests
from fyle.platform import Platform
from apps.fyle_hrms_mappings.models import ExpenseAttribute


class PlatformConnector:
Expand All @@ -20,8 +21,54 @@ def __init__(self, refresh_token: str, cluster_domain: str):
client_secret=settings.FYLE_CLIENT_SECRET,
refresh_token=refresh_token
)

def bulk_post_employees(self, employees_payload):
self.connection.v1beta.admin.employees.invite_bulk({'data': employees_payload})

def get_department_generator(self, query_params):
departments = self.connection.v1beta.admin.departments.list_all(query_params={
'order': 'id.desc'
})
return departments

def post_department(self, department):
self.connection.v1beta.admin.departments.post({"data": department})

def bulk_create_or_update_expense_attributes(self, attributes: List[dict], attribute_type, org_id, update_existing: bool = False) -> None:
"""
Bulk creates or updates expense attributes.
:param attributes: List of expense attributes.
:param update_existing: If True, updates/creates the existing expense attributes.
"""
ExpenseAttribute.bulk_create_or_update_expense_attributes(
attributes, attribute_type, org_id, update_existing
)

def sync_employees(self, org_id):
query_params = {'is_enabled': 'eq.true','order': 'updated_at.desc'}
attribute_type = 'EMPLOYEE'
generator = self.connection.v1beta.admin.employees.list_all(query_params)
for items in generator:
employee_attributes = []
for employee in items['data']:
employee_attributes.append({
'attribute_type': attribute_type,
'display_name': attribute_type.replace('_', ' ').title(),
'value': employee['user']['email'],
'source_id': employee['id'],
'active': True,
'detail': {
'user_id': employee['user_id'],
'employee_code': employee['code'],
'full_name': employee['user']['full_name'],
'location': employee['location'],
'department': employee['department']['name'] if employee['department'] else None,
'department_id': employee['department_id'],
'department_code': employee['department']['code'] if employee['department'] else None
}
})

self.bulk_create_or_update_expense_attributes(employee_attributes, attribute_type, org_id, True)

def post_request(url: str, body: Dict, api_headers: Dict) -> Dict:
"""
Expand Down
17 changes: 0 additions & 17 deletions fyle-employee_imports/bamboo_hr.py

This file was deleted.

35 changes: 0 additions & 35 deletions fyle-employee_imports/base.py

This file was deleted.

File renamed without changes.
43 changes: 43 additions & 0 deletions fyle_employee_imports/bamboo_hr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from typing import Dict
from apps.users.models import User
from apps.fyle_hrms_mappings.models import DestinationAttribute
from .base import FyleEmployeeImport
from bamboosdk.bamboohrsdk import BambooHrSDK
from apps.bamboohr.models import BambooHr


class BambooHrEmployeeImport(FyleEmployeeImport):

def __init__(self, org_id: int, user: User):
super().__init__(org_id, user)
bamboo_hr = BambooHr.objects.get(org_id__in=org_id)
self.bamboohr_sdk = BambooHrSDK(api_token=bamboo_hr.api_token, sub_domain=bamboo_hr.sub_domain)

def sync_hrms_employees(self):
employees = self.bamboohr_sdk.employees.get_all()
self.upsert_employees(employees)

def upsert_employees(self, employees: Dict):
attributes = []
for employee in employees['employees']:
supervisor = [employee['supervisorEmail']]
active_status = True if employee['status'] == 'Active' else False
detail = {
'email': employee['workEmail'] if employee['workEmail'] else None,
'department_name': employee['department'] if employee['department'] else None,
'full_name': employee['displayName'] if employee['displayName'] else None,
'approver_emails': supervisor,
}

attributes.append({
'attribute_type': 'EMPLOYEE',
'value': employee['displayName'],
'destination_id': employee['id'],
'detail': detail,
'active': active_status
})

DestinationAttribute.bulk_create_or_update_destination_attributes(
attributes=attributes, attribute_type='EMPLOYEE', org_id=self.org_id, update=True)

return []
Loading

0 comments on commit d9aa46f

Please sign in to comment.