brynq-sdk-nmbrs 2.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. brynq_sdk_nmbrs/__init__.py +226 -0
  2. brynq_sdk_nmbrs/absence.py +124 -0
  3. brynq_sdk_nmbrs/address.py +66 -0
  4. brynq_sdk_nmbrs/bank.py +125 -0
  5. brynq_sdk_nmbrs/children.py +100 -0
  6. brynq_sdk_nmbrs/companies.py +93 -0
  7. brynq_sdk_nmbrs/contract.py +132 -0
  8. brynq_sdk_nmbrs/costcenter.py +166 -0
  9. brynq_sdk_nmbrs/costunit.py +90 -0
  10. brynq_sdk_nmbrs/days.py +137 -0
  11. brynq_sdk_nmbrs/debtors.py +25 -0
  12. brynq_sdk_nmbrs/department.py +122 -0
  13. brynq_sdk_nmbrs/document.py +30 -0
  14. brynq_sdk_nmbrs/employees.py +196 -0
  15. brynq_sdk_nmbrs/employment.py +107 -0
  16. brynq_sdk_nmbrs/function.py +89 -0
  17. brynq_sdk_nmbrs/hours.py +252 -0
  18. brynq_sdk_nmbrs/leave.py +139 -0
  19. brynq_sdk_nmbrs/manager.py +294 -0
  20. brynq_sdk_nmbrs/salaries.py +85 -0
  21. brynq_sdk_nmbrs/salary_tables.py +242 -0
  22. brynq_sdk_nmbrs/schedules.py +84 -0
  23. brynq_sdk_nmbrs/schemas/__init__.py +37 -0
  24. brynq_sdk_nmbrs/schemas/absence.py +61 -0
  25. brynq_sdk_nmbrs/schemas/address.py +76 -0
  26. brynq_sdk_nmbrs/schemas/bank.py +83 -0
  27. brynq_sdk_nmbrs/schemas/contracts.py +60 -0
  28. brynq_sdk_nmbrs/schemas/costcenter.py +91 -0
  29. brynq_sdk_nmbrs/schemas/costunit.py +40 -0
  30. brynq_sdk_nmbrs/schemas/days.py +98 -0
  31. brynq_sdk_nmbrs/schemas/debtor.py +16 -0
  32. brynq_sdk_nmbrs/schemas/department.py +57 -0
  33. brynq_sdk_nmbrs/schemas/employees.py +153 -0
  34. brynq_sdk_nmbrs/schemas/employment.py +48 -0
  35. brynq_sdk_nmbrs/schemas/function.py +50 -0
  36. brynq_sdk_nmbrs/schemas/hours.py +121 -0
  37. brynq_sdk_nmbrs/schemas/leave.py +53 -0
  38. brynq_sdk_nmbrs/schemas/manager.py +126 -0
  39. brynq_sdk_nmbrs/schemas/salary.py +92 -0
  40. brynq_sdk_nmbrs/schemas/schedules.py +96 -0
  41. brynq_sdk_nmbrs/schemas/social_insurance.py +40 -0
  42. brynq_sdk_nmbrs/schemas/wage_tax.py +98 -0
  43. brynq_sdk_nmbrs/schemas/wagecomponents.py +114 -0
  44. brynq_sdk_nmbrs/social_insurance.py +52 -0
  45. brynq_sdk_nmbrs/wage_tax.py +164 -0
  46. brynq_sdk_nmbrs/wagecomponents.py +268 -0
  47. brynq_sdk_nmbrs-2.3.1.dist-info/METADATA +21 -0
  48. brynq_sdk_nmbrs-2.3.1.dist-info/RECORD +50 -0
  49. brynq_sdk_nmbrs-2.3.1.dist-info/WHEEL +5 -0
  50. brynq_sdk_nmbrs-2.3.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,122 @@
1
+ import math
2
+ import pandas as pd
3
+ import requests
4
+ from typing import Dict, Any
5
+ from .schemas.department import DepartmentCreate, EmployeeDepartmentUpdate, Period, EmployeeDepartmentGet, DepartmentGet
6
+ from brynq_sdk_functions import Functions
7
+
8
+
9
+ class EmployeeDepartment:
10
+ def __init__(self, nmbrs):
11
+ self.nmbrs = nmbrs
12
+
13
+ def get(self,
14
+ created_from: str = None,
15
+ employee_id: str = None) -> tuple[pd.DataFrame, pd.DataFrame]:
16
+ departments = pd.DataFrame()
17
+ for company in self.nmbrs.company_ids:
18
+ departments = pd.concat([departments, self._get(company, created_from, employee_id)])
19
+
20
+ valid_departments, invalid_departments = Functions.validate_data(df=departments, schema=EmployeeDepartmentGet, debug=True)
21
+
22
+ return valid_departments, invalid_departments
23
+
24
+ def _get(self,
25
+ company_id: str,
26
+ created_from: str = None,
27
+ employee_id: str = None) -> pd.DataFrame:
28
+ params = {}
29
+ if created_from:
30
+ params['createdFrom'] = created_from
31
+ if employee_id:
32
+ params['employeeId'] = employee_id
33
+ request = requests.Request(method='GET',
34
+ url=f"{self.nmbrs.base_url}companies/{company_id}/employees/departments",
35
+ params=params)
36
+
37
+ data = self.nmbrs.get_paginated_result(request)
38
+ df = pd.json_normalize(
39
+ data,
40
+ record_path='departments',
41
+ meta=['employeeId']
42
+ )
43
+
44
+ return df
45
+
46
+ def create(self, employee_id: str, data: Dict[str, Any]):
47
+ """
48
+ Create a new department for an employee using Pydantic validation.
49
+
50
+ Args:
51
+ employee_id: The ID of the employee
52
+ data: Dictionary containing department data with fields matching
53
+ the DepartmentCreate schema (using camelCase field names)
54
+
55
+ Returns:
56
+ Response from the API
57
+ """
58
+ # Validate with Pydantic model
59
+ nested_data = self.nmbrs.flat_dict_to_nested_dict(data, DepartmentCreate)
60
+ department_model = DepartmentCreate(**nested_data)
61
+
62
+ if self.nmbrs.mock_mode:
63
+ return department_model
64
+
65
+ # Convert validated model to dict for API payload
66
+ payload = department_model.model_dump(exclude_none=True, by_alias=True)
67
+
68
+ # Send request
69
+ resp = self.nmbrs.session.post(
70
+ url=f"{self.nmbrs.base_url}employees/{employee_id}/department",
71
+ json=payload,
72
+ timeout=self.nmbrs.timeout
73
+ )
74
+ return resp
75
+
76
+ def update(self, employee_id: str, data: Dict[str, Any]):
77
+ """
78
+ Update a department for an employee using Pydantic validation.
79
+
80
+ Args:
81
+ employee_id: The ID of the employee
82
+ data: Dictionary containing department data with fields matching
83
+ the DepartmentUpdate schema (using camelCase field names)
84
+
85
+ Returns:
86
+ Response from the API
87
+ """
88
+ # Validate with Pydantic model
89
+ nested_data = self.nmbrs.flat_dict_to_nested_dict(data, EmployeeDepartmentUpdate)
90
+ department_model = EmployeeDepartmentUpdate(**nested_data)
91
+
92
+ if self.nmbrs.mock_mode:
93
+ return department_model
94
+
95
+ # Convert validated model to dict for API payload
96
+ payload = department_model.model_dump(exclude_none=True, by_alias=True)
97
+
98
+ # Send request
99
+ resp = self.nmbrs.session.put(
100
+ url=f"{self.nmbrs.base_url}employees/{employee_id}/department",
101
+ json=payload,
102
+ timeout=self.nmbrs.timeout
103
+ )
104
+ return resp
105
+
106
+
107
+
108
+ class Departments:
109
+ def __init__(self, nmbrs):
110
+ self.nmbrs = nmbrs
111
+
112
+ def get(self,
113
+ debtor_id: str) -> pd.DataFrame:
114
+ request = requests.Request(method='GET',
115
+ url=f"{self.nmbrs.base_url}debtors/{debtor_id}/departments")
116
+
117
+ data = self.nmbrs.get_paginated_result(request)
118
+
119
+ df = pd.DataFrame(data)
120
+ valid_departments, invalid_departments = Functions.validate_data(df=df, schema=DepartmentGet, debug=True)
121
+
122
+ return valid_departments, invalid_departments
@@ -0,0 +1,30 @@
1
+ from io import BytesIO
2
+
3
+ import pandas as pd
4
+ import requests
5
+
6
+
7
+ class Payslip:
8
+ def __init__(self, nmbrs):
9
+ self.nmbrs = nmbrs
10
+
11
+ def get(self,
12
+ employee_id: str,
13
+ period: int = None,
14
+ year: int = None) -> pd.DataFrame:
15
+ params = {}
16
+ if period:
17
+ params['period'] = period
18
+ if year:
19
+ params['year'] = year
20
+ resp = self.nmbrs.session.get(f"{self.nmbrs.base_url}employees/{employee_id}/payslipperperiod/",
21
+ params=params,
22
+ timeout=self.nmbrs.timeout)
23
+ resp.raise_for_status()
24
+ task_id = resp.json()['taskId']
25
+
26
+ resp = self.nmbrs.session.get(f"{self.nmbrs.base_url}documents/{task_id}", timeout=self.nmbrs.timeout)
27
+
28
+ return BytesIO(resp.content)
29
+
30
+
@@ -0,0 +1,196 @@
1
+ import pandas as pd
2
+ import requests
3
+ from pydantic import BaseModel
4
+
5
+ from brynq_sdk_functions import Functions
6
+ from typing import Dict, Any, Optional
7
+
8
+ from .wage_tax import WageTax
9
+
10
+ from .document import Payslip
11
+ from .address import Address
12
+ from .contract import Contract
13
+ from .costcenter import EmployeeCostcenter
14
+ from .department import EmployeeDepartment
15
+ from .employment import Employment
16
+ from .function import EmployeeFunction
17
+ from .hours import VariableHours, FixedHours
18
+ from .schedules import Schedule
19
+ from .salaries import Salaries
20
+ from .bank import Bank
21
+ from .days import VariableDays
22
+ from .wagecomponents import EmployeeVariableWageComponents, EmployeeFixedWageComponents
23
+ from .leave import Leave, LeaveBalance
24
+ from .schemas.employees import (
25
+ BsnGet, EmployeeGet, EmployeeCreate, EmployeeUpdate, EmployeeDelete,
26
+ BasicInfo, BirthInfo, ContactInfo, PartnerInfo, Period, AdditionalEmployeeInfo,
27
+ CreateEmployeePersonalInfo
28
+ )
29
+
30
+
31
+ class Employees:
32
+ def __init__(self, nmbrs):
33
+ self.nmbrs = nmbrs
34
+ self.address = Address(nmbrs)
35
+ self.functions = EmployeeFunction(nmbrs)
36
+ self.contract = Contract(nmbrs)
37
+ self.departments = EmployeeDepartment(nmbrs)
38
+ self.costcenter = EmployeeCostcenter(nmbrs)
39
+ self.schedule = Schedule(nmbrs)
40
+ self.employment = Employment(nmbrs)
41
+ self.variable_hours = VariableHours(nmbrs)
42
+ self.fixed_hours = FixedHours(nmbrs)
43
+ self.variable_days = VariableDays(nmbrs)
44
+ self.salaries = Salaries(nmbrs)
45
+ self.variable_wagecomponents = EmployeeVariableWageComponents(nmbrs)
46
+ self.fixed_wagecomponents = EmployeeFixedWageComponents(nmbrs)
47
+ self.banks = Bank(nmbrs)
48
+ self.payslips = Payslip(nmbrs)
49
+ self.wage_tax = WageTax(nmbrs)
50
+ self.leave = Leave(nmbrs)
51
+ self.leave_balance = LeaveBalance(nmbrs)
52
+
53
+ def get(self,
54
+ employee_type: str = None
55
+ ) -> (pd.DataFrame, pd.DataFrame):
56
+ employees = pd.DataFrame()
57
+ for company in self.nmbrs.company_ids:
58
+ employees = pd.concat([employees, self._get(company, employee_type)])
59
+
60
+ valid_employees, invalid_employees = Functions.validate_data(df=employees, schema=EmployeeGet, debug=True)
61
+
62
+ return valid_employees, invalid_employees
63
+
64
+ def _get(self,
65
+ company_id: str,
66
+ employee_type: str = None) -> pd.DataFrame:
67
+ params = {} if employee_type is None else {'employeeType': employee_type}
68
+ request = requests.Request(method='GET',
69
+ url=f"{self.nmbrs.base_url}companies/{company_id}/employees/personalinfo",
70
+ params=params)
71
+
72
+ data = self.nmbrs.get_paginated_result(request)
73
+ df = pd.json_normalize(
74
+ data,
75
+ record_path='info',
76
+ meta=['employeeId']
77
+ )
78
+ df['companyId'] = company_id
79
+
80
+ df['createdAt'] = pd.to_datetime(df['createdAt'])
81
+ df = df.loc[df.groupby('employeeId')['createdAt'].idxmax()]
82
+ df = df.reset_index(drop=True)
83
+
84
+ return df
85
+
86
+ def get_private_info(self) -> str:
87
+ combined = []
88
+ for company_id in self.nmbrs.company_ids:
89
+ request = requests.Request(method='GET',
90
+ url=f"{self.nmbrs.base_url}companies/{company_id}/employees/privateInfos")
91
+ data = self.nmbrs.get_paginated_result(request)
92
+ df = pd.json_normalize(
93
+ data,
94
+ record_path='privateInfos',
95
+ meta=['employeeId']
96
+ )
97
+ df['companyId'] = company_id
98
+ combined.append(df)
99
+ df = pd.concat(combined, ignore_index=True)
100
+ valid_bsn, invalid_bsn = Functions.validate_data(df, BsnGet)
101
+
102
+ return valid_bsn, invalid_bsn
103
+
104
+ def get_default_templates(self) -> pd.DataFrame:
105
+ default_templates = pd.DataFrame()
106
+ for company in self.nmbrs.company_ids:
107
+ default_templates_temp = self._get_default_templates(company)
108
+ default_templates_temp['companyId'] = company
109
+ default_templates = pd.concat([default_templates, default_templates_temp])
110
+
111
+ # valid_default_templates, invalid_default_templates = Functions.validate_data(df=default_templates, schema=EmployeeGet, debug=True)
112
+
113
+ return default_templates
114
+
115
+
116
+ def _get_default_templates(self, company_id: str, employee_type: str = None) -> pd.DataFrame:
117
+ params = {} if employee_type is None else {'employeeType': employee_type}
118
+ request = requests.Request(method='GET',
119
+ url=f"{self.nmbrs.base_url}companies/{company_id}/defaulttemplates",
120
+ params=params)
121
+ data = self.nmbrs.get_paginated_result(request)
122
+ return pd.DataFrame(data)
123
+
124
+ def create(self, company_id: str, data: Dict[str, Any]):
125
+ """
126
+ Create a new employee using Pydantic validation.
127
+
128
+ Args:
129
+ company_id: The ID of the company
130
+ data: Dictionary structured according to the EmployeeCreate schema with:
131
+ - PersonalInfo: containing basicInfo, birthInfo, contactInfo, etc.
132
+ - AdditionalEmployeeInfo: containing service date, etc.
133
+
134
+ Returns:
135
+ Response from the API
136
+ """
137
+ # Validate with Pydantic model
138
+ nested_data = self.nmbrs.flat_dict_to_nested_dict(data, EmployeeCreate)
139
+ employee_model = EmployeeCreate(**nested_data)
140
+
141
+ if self.nmbrs.mock_mode:
142
+ return employee_model
143
+
144
+ # Convert validated model to dict for API payload
145
+ payload = employee_model.model_dump(exclude_none=True, by_alias=True)
146
+
147
+ # Send request
148
+ resp = self.nmbrs.session.post(
149
+ url=f"{self.nmbrs.base_url}companies/{company_id}/employees",
150
+ json=payload,
151
+ timeout=self.nmbrs.timeout
152
+ )
153
+ return resp
154
+
155
+ def update(self, employee_id: str, data: Dict[str, Any]):
156
+ """
157
+ Update an employee using Pydantic validation.
158
+
159
+ Args:
160
+ employee_id: The ID of the employee
161
+ data: Dictionary structured according to the EmployeeUpdate schema with:
162
+ - employeeId: The ID of the employee to update
163
+ - personalInfo: containing any of basicInfo, birthInfo, contactInfo, etc.
164
+
165
+ Returns:
166
+ Response from the API
167
+ """
168
+ # Validate with Pydantic model
169
+ nested_data = self.nmbrs.flat_dict_to_nested_dict(data, EmployeeUpdate)
170
+ employee_model = EmployeeUpdate(**nested_data)
171
+
172
+ if self.nmbrs.mock_mode:
173
+ return employee_model
174
+
175
+ # Convert validated model to dict for API payload
176
+ payload = employee_model.model_dump(exclude_none=True, by_alias=True)
177
+
178
+ # Send request
179
+ resp = self.nmbrs.session.put(
180
+ url=f"{self.nmbrs.base_url}employees/{employee_id}/personalInfo",
181
+ json=payload,
182
+ timeout=self.nmbrs.timeout
183
+ )
184
+
185
+ # Handle social security number update if present
186
+ if 'socialSecurityNumber' in data:
187
+ social_security_payload = {
188
+ "socialSecurityNumber": data['socialSecurityNumber']
189
+ }
190
+ resp = self.nmbrs.session.put(
191
+ url=f"{self.nmbrs.base_url}employees/{employee_id}/social_security_number",
192
+ json=social_security_payload,
193
+ timeout=self.nmbrs.timeout
194
+ )
195
+
196
+ return resp
@@ -0,0 +1,107 @@
1
+ import math
2
+ import pandas as pd
3
+ import requests
4
+ from brynq_sdk_functions import Functions
5
+ from typing import Dict, Any
6
+ from .schemas.employment import EmploymentGet, EmploymentCreate, EmploymentUpdate, EmploymentDelete
7
+
8
+
9
+ class Employment:
10
+ def __init__(self, nmbrs):
11
+ self.nmbrs = nmbrs
12
+
13
+ def get(self,
14
+ changed_from: str = None,
15
+ created_from: str = None,
16
+ employee_id: str = None) -> tuple[pd.DataFrame, pd.DataFrame]:
17
+ employments = pd.DataFrame()
18
+ for company in self.nmbrs.company_ids:
19
+ employments = pd.concat([employments, self._get(company, changed_from, created_from, employee_id)])
20
+
21
+ valid_employments, invalid_employments = Functions.validate_data(df=employments, schema=EmploymentGet, debug=True)
22
+
23
+ return valid_employments, invalid_employments
24
+
25
+ def _get(self,
26
+ company_id: str,
27
+ changed_from: str = None,
28
+ created_from: str = None,
29
+ employee_id: str = None) -> pd.DataFrame:
30
+ params = {}
31
+ if created_from:
32
+ params['createdFrom'] = created_from
33
+ if employee_id:
34
+ params['changedFrom'] = changed_from
35
+ if employee_id:
36
+ params['employeeId'] = employee_id
37
+ request = requests.Request(method='GET',
38
+ url=f"{self.nmbrs.base_url}companies/{company_id}/employees/employments",
39
+ params=params)
40
+ data = self.nmbrs.get_paginated_result(request)
41
+ df = pd.json_normalize(
42
+ data,
43
+ record_path='employments',
44
+ meta=['employeeId']
45
+ )
46
+
47
+ return df
48
+
49
+ def create(self, employee_id: str, data: Dict[str, Any]):
50
+ """
51
+ Create a new employment record for an employee using Pydantic validation.
52
+
53
+ Args:
54
+ employee_id: The ID of the employee
55
+ data: Dictionary containing employment data with fields matching
56
+ the EmploymentCreate schema (using camelCase field names)
57
+
58
+ Returns:
59
+ Response from the API
60
+ """
61
+ # Validate with Pydantic model
62
+ nested_data = self.nmbrs.flat_dict_to_nested_dict(data, EmploymentCreate)
63
+ employment_model = EmploymentCreate(**nested_data)
64
+
65
+ if self.nmbrs.mock_mode:
66
+ return employment_model
67
+
68
+ # Convert validated model to dict for API payload
69
+ payload = employment_model.model_dump(exclude_none=True, by_alias=True)
70
+
71
+ # Send request
72
+ resp = self.nmbrs.session.post(
73
+ url=f"{self.nmbrs.base_url}employees/{employee_id}/employment",
74
+ json=payload,
75
+ timeout=self.nmbrs.timeout
76
+ )
77
+ return resp
78
+
79
+ def update(self, employee_id: str, data: Dict[str, Any]):
80
+ """
81
+ Update an employment record for an employee using Pydantic validation.
82
+
83
+ Args:
84
+ employee_id: The ID of the employee
85
+ data: Dictionary containing employment data with fields matching
86
+ the EmploymentUpdate schema (using camelCase field names)
87
+
88
+ Returns:
89
+ Response from the API
90
+ """
91
+ # Validate with Pydantic model
92
+ nested_data = self.nmbrs.flat_dict_to_nested_dict(data, EmploymentUpdate)
93
+ employment_model = EmploymentUpdate(**nested_data)
94
+
95
+ if self.nmbrs.mock_mode:
96
+ return employment_model
97
+
98
+ # Convert validated model to dict for API payload
99
+ payload = employment_model.model_dump(exclude_none=True, by_alias=True)
100
+
101
+ # Send request
102
+ resp = self.nmbrs.session.put(
103
+ url=f"{self.nmbrs.base_url}employees/{employee_id}/employment",
104
+ json=payload,
105
+ timeout=self.nmbrs.timeout
106
+ )
107
+ return resp
@@ -0,0 +1,89 @@
1
+ import pandas as pd
2
+ import requests
3
+ from brynq_sdk_functions import Functions as BrynQFunctions
4
+ import math
5
+ from typing import Dict, Any
6
+ from .schemas.function import EmployeeFunctionGet, FunctionUpdate, FunctionGet
7
+
8
+
9
+ class EmployeeFunction:
10
+ def __init__(self, nmbrs):
11
+ self.nmbrs = nmbrs
12
+
13
+ def get(self,
14
+ created_from: str = None) -> tuple[pd.DataFrame, pd.DataFrame]:
15
+ functions = pd.DataFrame()
16
+ for company in self.nmbrs.company_ids:
17
+ functions = pd.concat([functions, self._get(company, created_from)])
18
+
19
+ valid_functions, invalid_functions = BrynQFunctions.validate_data(df=functions, schema=EmployeeFunctionGet, debug=True)
20
+
21
+ return valid_functions, invalid_functions
22
+
23
+ def _get(self,
24
+ company_id: str,
25
+ created_from: str = None) -> pd.DataFrame:
26
+ params = {}
27
+ if created_from:
28
+ params['createdFrom'] = created_from
29
+ try:
30
+ request = requests.Request(method='GET', url=f"{self.nmbrs.base_url}companies/{company_id}/employees/functions", params=params)
31
+ data = self.nmbrs.get_paginated_result(request)
32
+ df = pd.json_normalize(
33
+ data,
34
+ record_path='functions',
35
+ meta=['employeeId']
36
+ )
37
+ except requests.HTTPError as e:
38
+ df = pd.DataFrame()
39
+ return df
40
+
41
+ def update(self, employee_id: str, data: Dict[str, Any]):
42
+ """
43
+ Update a function for an employee using Pydantic validation.
44
+
45
+ Args:
46
+ employee_id: The ID of the employee
47
+ data: Dictionary containing function data with fields matching
48
+ the FunctionUpdate schema (using camelCase field names)
49
+
50
+ Returns:
51
+ Response from the API
52
+ """
53
+ # Validate with Pydantic model
54
+ nested_data = self.nmbrs.flat_dict_to_nested_dict(data, FunctionUpdate)
55
+ function_model = FunctionUpdate(**nested_data)
56
+
57
+ if self.nmbrs.mock_mode:
58
+ return function_model
59
+
60
+ # Convert validated model to dict for API payload
61
+ payload = function_model.model_dump(exclude_none=True, by_alias=True)
62
+
63
+ # Send request
64
+ resp = self.nmbrs.session.put(
65
+ url=f"{self.nmbrs.base_url}employees/{employee_id}/function",
66
+ json=payload,
67
+ timeout=self.nmbrs.timeout
68
+ )
69
+ return resp
70
+
71
+
72
+
73
+ class Functions:
74
+ def __init__(self, nmbrs):
75
+ self.nmbrs = nmbrs
76
+
77
+ def get(self, debtor_id: str) -> (pd.DataFrame, pd.DataFrame):
78
+ try:
79
+ request = requests.Request(method='GET',
80
+ url=f"{self.nmbrs.base_url}debtors/{debtor_id}/functions")
81
+
82
+ data = self.nmbrs.get_paginated_result(request)
83
+ df = pd.DataFrame(data)
84
+ valid_functions, invalid_functions = BrynQFunctions.validate_data(df=df, schema=FunctionGet, debug=True)
85
+
86
+ except requests.HTTPError as e:
87
+ df = pd.DataFrame()
88
+
89
+ return valid_functions, invalid_functions