brynq-sdk-zenegy 1.3.3__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.
- brynq_sdk_zenegy/__init__.py +23 -0
- brynq_sdk_zenegy/absence.py +100 -0
- brynq_sdk_zenegy/companies.py +43 -0
- brynq_sdk_zenegy/cost_center.py +80 -0
- brynq_sdk_zenegy/departments.py +77 -0
- brynq_sdk_zenegy/employee_documents.py +40 -0
- brynq_sdk_zenegy/employees.py +301 -0
- brynq_sdk_zenegy/global_value_sets.py +260 -0
- brynq_sdk_zenegy/global_values.py +265 -0
- brynq_sdk_zenegy/paychecks.py +119 -0
- brynq_sdk_zenegy/payroll.py +117 -0
- brynq_sdk_zenegy/payslips.py +43 -0
- brynq_sdk_zenegy/pensions.py +118 -0
- brynq_sdk_zenegy/schemas/__init__.py +30 -0
- brynq_sdk_zenegy/schemas/absences.py +393 -0
- brynq_sdk_zenegy/schemas/companies.py +42 -0
- brynq_sdk_zenegy/schemas/company_cost_centers.py +48 -0
- brynq_sdk_zenegy/schemas/company_departments.py +147 -0
- brynq_sdk_zenegy/schemas/employee_documents.py +30 -0
- brynq_sdk_zenegy/schemas/employee_pay_checks.py +169 -0
- brynq_sdk_zenegy/schemas/employee_pensions.py +140 -0
- brynq_sdk_zenegy/schemas/employees.py +2372 -0
- brynq_sdk_zenegy/schemas/global_value_sets.py +185 -0
- brynq_sdk_zenegy/schemas/global_values.py +433 -0
- brynq_sdk_zenegy/schemas/payrolls.py +134 -0
- brynq_sdk_zenegy/schemas/payslips.py +32 -0
- brynq_sdk_zenegy/schemas/supplements_and_deductions_rates.py +189 -0
- brynq_sdk_zenegy/supplements_and_deductions_rates.py +71 -0
- brynq_sdk_zenegy/zenegy.py +221 -0
- brynq_sdk_zenegy-1.3.3.dist-info/METADATA +16 -0
- brynq_sdk_zenegy-1.3.3.dist-info/RECORD +33 -0
- brynq_sdk_zenegy-1.3.3.dist-info/WHEEL +5 -0
- brynq_sdk_zenegy-1.3.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
from .schemas.payrolls import PayrollsGet
|
|
2
|
+
import requests
|
|
3
|
+
from uuid import UUID
|
|
4
|
+
from typing import Tuple
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from brynq_sdk_functions import Functions
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Payrolls:
|
|
10
|
+
"""
|
|
11
|
+
Handles all payroll-related operations in Zenegy API
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, zenegy):
|
|
15
|
+
"""
|
|
16
|
+
Initialize the Payrolls class.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
zenegy: The Zenegy instance to use for API calls
|
|
20
|
+
"""
|
|
21
|
+
self.zenegy = zenegy
|
|
22
|
+
self.endpoint = f"api/companies/{self.zenegy.company_uid}/payroll"
|
|
23
|
+
|
|
24
|
+
def get_employee_payrolls(self, payroll_uid: UUID, employee_uid: UUID) -> Tuple[pd.DataFrame, pd.DataFrame]:
|
|
25
|
+
"""
|
|
26
|
+
Get employee payrolls for a specific payroll and employee.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
payroll_uid (UUID): The payroll uid
|
|
30
|
+
employee_uid (UUID): The employee uid
|
|
31
|
+
Returns:
|
|
32
|
+
Tuple of (valid_data, invalid_data) DataFrames
|
|
33
|
+
"""
|
|
34
|
+
try:
|
|
35
|
+
endpoint = f"{self.endpoint}/{payroll_uid}/employees/{employee_uid}"
|
|
36
|
+
content = self.zenegy.get(endpoint=endpoint)
|
|
37
|
+
|
|
38
|
+
# Normalize the response (direct list of dicts)
|
|
39
|
+
df = pd.DataFrame(content)
|
|
40
|
+
if df.empty:
|
|
41
|
+
return pd.DataFrame(), pd.DataFrame()
|
|
42
|
+
|
|
43
|
+
# Validate against schema
|
|
44
|
+
valid_data, invalid_data = Functions.validate_data(df, PayrollsGet)
|
|
45
|
+
|
|
46
|
+
return valid_data, invalid_data
|
|
47
|
+
except Exception as e:
|
|
48
|
+
raise Exception(f"Failed to retrieve employee payrolls: {str(e)}") from e
|
|
49
|
+
|
|
50
|
+
def get_by_id(self, payroll_uid: UUID) -> Tuple[pd.DataFrame, pd.DataFrame]:
|
|
51
|
+
"""
|
|
52
|
+
GetPayroll
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
payroll_uid (UUID): The payroll uid
|
|
56
|
+
Returns:
|
|
57
|
+
Tuple of (valid_data, invalid_data) DataFrames
|
|
58
|
+
"""
|
|
59
|
+
try:
|
|
60
|
+
endpoint = f"{self.endpoint}/{payroll_uid}"
|
|
61
|
+
content = self.zenegy.get(endpoint=endpoint)
|
|
62
|
+
|
|
63
|
+
# Normalize the response using record_path for employees array
|
|
64
|
+
df = pd.json_normalize(
|
|
65
|
+
[content],
|
|
66
|
+
record_path='employees',
|
|
67
|
+
meta=['uid', 'type', 'periodFrom', 'periodTo', 'dispositionDate', 'status', 'hasHolidayPayment', 'hasBenefitPackage', 'hasBenefitPackageTwo', 'hasAmPension', 'hasApprovalFlowEnabled', 'company', 'hasHolidaySupplementPayout', 'disablePayslipNotification', 'sendPayslipNotificationOn', 'hasHolidayPaymentPayout', 'hasHolidayPaymentToHolidayPayPayout', 'hasBenefitPackagePayout', 'hasBenefitPackageTwoPayout', 'isAlreadyPaid', 'isEligibleForRevert', 'payrollRegistrationPeriods', 'note', 'isForced', 'hasTimeInLieuPayout', 'payslipStatus', 'isPayrollApprovalEnabledForPayroll', 'disablePayslipGeneration', 'isTrackingNegativeSalaryEnabled', 'isCompanyExtraEntitlementInHours', 'isExtraHolidayEntitlementInHoursEnabled', 'revertType', 'hasHolidayPaymentTaxationAndTransferToNextYear', 'hasHolidayPaymentNettoPayout', 'hasTransferShNettoAndPayout', 'hasShNetPayout', 'hasFifthHolidayWeekPayout', 'extraPayrollRun', 'isCompletedWithAmAccounting', 'failedPayrollUid'],
|
|
68
|
+
record_prefix='employee__',
|
|
69
|
+
sep='__'
|
|
70
|
+
)
|
|
71
|
+
if df.empty:
|
|
72
|
+
return pd.DataFrame(), pd.DataFrame()
|
|
73
|
+
|
|
74
|
+
# Validate against schema
|
|
75
|
+
valid_data, invalid_data = Functions.validate_data(df, PayrollsGet)
|
|
76
|
+
|
|
77
|
+
return valid_data, invalid_data
|
|
78
|
+
except Exception as e:
|
|
79
|
+
raise Exception(f"Failed to retrieve payroll by ID: {str(e)}") from e
|
|
80
|
+
|
|
81
|
+
def delete(self, payroll_uid: UUID) -> requests.Response:
|
|
82
|
+
"""
|
|
83
|
+
CancelPayroll
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
company_uid (UUID): The company uid
|
|
87
|
+
Args:
|
|
88
|
+
payroll_uid (UUID): The payroll uid
|
|
89
|
+
Returns:
|
|
90
|
+
requests.Response: The API response
|
|
91
|
+
"""
|
|
92
|
+
endpoint = f"{self.endpoint}/{payroll_uid}"
|
|
93
|
+
try:
|
|
94
|
+
response = self.zenegy.delete(endpoint=endpoint)
|
|
95
|
+
self.zenegy.raise_for_status_with_details(response)
|
|
96
|
+
return response
|
|
97
|
+
except Exception as e:
|
|
98
|
+
raise Exception(f"Failed to delete payroll: {str(e)}")
|
|
99
|
+
|
|
100
|
+
def delete_employee_payroll(self, payroll_uid: UUID,
|
|
101
|
+
employee_payroll_uid: UUID) -> requests.Response:
|
|
102
|
+
"""
|
|
103
|
+
DeleteEmployeePayrollAsync
|
|
104
|
+
Args:
|
|
105
|
+
payroll_uid (UUID): The payroll uid
|
|
106
|
+
Args:
|
|
107
|
+
employee_payroll_uid (UUID): The employee payroll uid
|
|
108
|
+
Returns:
|
|
109
|
+
requests.Response: The API response
|
|
110
|
+
"""
|
|
111
|
+
endpoint_path = f"{self.endpoint}/{payroll_uid}/employees/{employee_payroll_uid}"
|
|
112
|
+
try:
|
|
113
|
+
response = self.zenegy.delete(endpoint=endpoint_path)
|
|
114
|
+
self.zenegy.raise_for_status_with_details(response)
|
|
115
|
+
return response
|
|
116
|
+
except Exception as e:
|
|
117
|
+
raise Exception(f"Failed to delete employee payroll: {str(e)}")
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from .schemas.payslips import PayslipsGet
|
|
2
|
+
from uuid import UUID
|
|
3
|
+
from typing import Tuple
|
|
4
|
+
import pandas as pd
|
|
5
|
+
from brynq_sdk_functions import Functions
|
|
6
|
+
|
|
7
|
+
class Payslips:
|
|
8
|
+
"""
|
|
9
|
+
Handles all payslip-related operations in Zenegy API
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, zenegy):
|
|
13
|
+
"""
|
|
14
|
+
Initialize the Payslips class.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
zenegy: The Zenegy instance to use for API calls
|
|
18
|
+
"""
|
|
19
|
+
self.zenegy = zenegy
|
|
20
|
+
|
|
21
|
+
def get(self, employee_uid: UUID) -> Tuple[pd.DataFrame, pd.DataFrame]:
|
|
22
|
+
"""
|
|
23
|
+
GetEmployeePayslips
|
|
24
|
+
Args:
|
|
25
|
+
employee_uid (UUID): The employee uid
|
|
26
|
+
Returns:
|
|
27
|
+
Tuple of (valid_data, invalid_data) DataFrames
|
|
28
|
+
"""
|
|
29
|
+
try:
|
|
30
|
+
endpoint = f"api/companies/{self.zenegy.company_uid}/employees/{employee_uid}/payslips"
|
|
31
|
+
content = self.zenegy.get(endpoint=endpoint)
|
|
32
|
+
|
|
33
|
+
# Normalize the response (data field contains the list)
|
|
34
|
+
df = pd.json_normalize(content.get("data", []), sep='__')
|
|
35
|
+
if df.empty:
|
|
36
|
+
return pd.DataFrame(), pd.DataFrame()
|
|
37
|
+
|
|
38
|
+
# Validate against schema
|
|
39
|
+
valid_data, invalid_data = Functions.validate_data(df, PayslipsGet)
|
|
40
|
+
|
|
41
|
+
return valid_data, invalid_data
|
|
42
|
+
except Exception as e:
|
|
43
|
+
raise Exception(f"Failed to retrieve payslips: {str(e)}") from e
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from uuid import UUID
|
|
3
|
+
from .schemas.employee_pensions import (EmployeePensionCreate,
|
|
4
|
+
PensionGet)
|
|
5
|
+
from brynq_sdk_functions import Functions
|
|
6
|
+
from typing import Dict, Any, List, Tuple
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Pensions:
|
|
11
|
+
"""
|
|
12
|
+
Handles all employeepensions-related operations in Zenegy API
|
|
13
|
+
"""
|
|
14
|
+
def __init__(self, zenegy):
|
|
15
|
+
"""
|
|
16
|
+
Initialize the Employeepensions class.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
zenegy: The Zenegy instance to use for API calls
|
|
20
|
+
"""
|
|
21
|
+
self.zenegy = zenegy
|
|
22
|
+
self.endpoint = f"api/companies/{self.zenegy.company_uid}/pensions/bulk"
|
|
23
|
+
|
|
24
|
+
def get(self, employee_uid: UUID) -> Tuple[pd.DataFrame, pd.DataFrame]:
|
|
25
|
+
"""
|
|
26
|
+
GetEmployeePensionsAsync
|
|
27
|
+
Args:
|
|
28
|
+
employee_uid (UUID): The employee uid
|
|
29
|
+
Returns:
|
|
30
|
+
Tuple of (valid_data, invalid_data) DataFrames
|
|
31
|
+
"""
|
|
32
|
+
try:
|
|
33
|
+
endpoint = f"api/companies/{self.zenegy.company_uid}/employees/{employee_uid}/pensions"
|
|
34
|
+
content = self.zenegy.get(endpoint=endpoint)
|
|
35
|
+
|
|
36
|
+
# Get data from response
|
|
37
|
+
data = content.get("data", [])
|
|
38
|
+
if data:
|
|
39
|
+
# Normalize the data
|
|
40
|
+
df = pd.json_normalize(
|
|
41
|
+
data,
|
|
42
|
+
sep='__'
|
|
43
|
+
)
|
|
44
|
+
if df.empty:
|
|
45
|
+
return pd.DataFrame(), pd.DataFrame()
|
|
46
|
+
# Validate data using schema
|
|
47
|
+
valid_data, invalid_data = Functions.validate_data(df, PensionGet)
|
|
48
|
+
return valid_data, invalid_data
|
|
49
|
+
return pd.DataFrame(), pd.DataFrame()
|
|
50
|
+
except Exception as e:
|
|
51
|
+
raise Exception(f"Failed to retrieve pensions: {str(e)}") from e
|
|
52
|
+
|
|
53
|
+
def get_by_id(self, employee_uid: UUID, employee_pension_uid: UUID) -> Tuple[pd.DataFrame, pd.DataFrame]:
|
|
54
|
+
"""
|
|
55
|
+
GetEmployeePensionAsync
|
|
56
|
+
Args:
|
|
57
|
+
employee_uid (UUID): The employee uid
|
|
58
|
+
employee_pension_uid (UUID): The employee pension uid
|
|
59
|
+
Returns:
|
|
60
|
+
Tuple of (valid_data, invalid_data) DataFrames
|
|
61
|
+
"""
|
|
62
|
+
try:
|
|
63
|
+
endpoint = f"api/companies/{self.zenegy.company_uid}/employees/{employee_uid}/pensions/{employee_pension_uid}"
|
|
64
|
+
content = self.zenegy.get(endpoint=endpoint)
|
|
65
|
+
|
|
66
|
+
# Normalize the data (content is already a dict)
|
|
67
|
+
df = pd.json_normalize(
|
|
68
|
+
[content], # Wrap single object in list for normalization
|
|
69
|
+
sep='__'
|
|
70
|
+
)
|
|
71
|
+
if df.empty:
|
|
72
|
+
return pd.DataFrame(), pd.DataFrame()
|
|
73
|
+
|
|
74
|
+
# Validate data using schema
|
|
75
|
+
valid_data, invalid_data = Functions.validate_data(df, PensionGet)
|
|
76
|
+
return valid_data, invalid_data
|
|
77
|
+
except Exception as e:
|
|
78
|
+
raise Exception(f"Failed to retrieve pension by ID: {str(e)}") from e
|
|
79
|
+
|
|
80
|
+
def create(self, employee_uid: UUID, data: Dict[str, Any]) -> requests.Response:
|
|
81
|
+
"""
|
|
82
|
+
InsertEmployeePensionAsync
|
|
83
|
+
Args:
|
|
84
|
+
employee_uid (UUID): The employee uid
|
|
85
|
+
Args:
|
|
86
|
+
data (Dict[str, Any]): The data
|
|
87
|
+
Returns:
|
|
88
|
+
requests.Response: The API response
|
|
89
|
+
"""
|
|
90
|
+
endpoint = f"api/companies/{self.zenegy.company_uid}/employees/{employee_uid}/pensions"
|
|
91
|
+
# Validate the data using Pydantic
|
|
92
|
+
try:
|
|
93
|
+
valid_data = EmployeePensionCreate(**data)
|
|
94
|
+
if valid_data:
|
|
95
|
+
req_body = valid_data.model_dump(by_alias=True, exclude_none=True,mode="json")
|
|
96
|
+
response = self.zenegy.post(endpoint=endpoint, json=req_body)
|
|
97
|
+
self.zenegy.raise_for_status_with_details(response)
|
|
98
|
+
return response
|
|
99
|
+
except Exception as e:
|
|
100
|
+
raise Exception(f"Error creating pension data: {str(e)}")
|
|
101
|
+
|
|
102
|
+
def delete(self, employee_uid: UUID, employee_pension_uid: UUID) -> requests.Response:
|
|
103
|
+
"""
|
|
104
|
+
DeleteEmployeePensionAsync
|
|
105
|
+
Args:
|
|
106
|
+
employee_uid (UUID): The employee uid
|
|
107
|
+
Args:
|
|
108
|
+
employee_pension_uid (UUID): The employee pension uid
|
|
109
|
+
Returns:
|
|
110
|
+
requests.Response: The API response
|
|
111
|
+
"""
|
|
112
|
+
endpoint = f"api/companies/{self.zenegy.company_uid}/employees/{employee_uid}/pensions/{employee_pension_uid}"
|
|
113
|
+
try:
|
|
114
|
+
response = self.zenegy.delete(endpoint=endpoint)
|
|
115
|
+
self.zenegy.raise_for_status_with_details(response)
|
|
116
|
+
return response
|
|
117
|
+
except Exception as e:
|
|
118
|
+
raise Exception(f"Failed to delete pension: {str(e)}")
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Schema definitions for Zenegy package"""
|
|
2
|
+
|
|
3
|
+
from .absences import AbsenceGet, CreateAbsenceRequest, UpdateAbsenceRequest
|
|
4
|
+
from .companies import CompaniesGet
|
|
5
|
+
from .company_cost_centers import CostCentersGet, CostCenterCreate
|
|
6
|
+
from .company_departments import DepartmentsGet
|
|
7
|
+
from .employees import EmployeesGet, EmployeesGetById, EmployeeCreate, EmployeeUpsert, EmployeeUpdate
|
|
8
|
+
from .employee_pensions import PensionGet, EmployeePensionCreate
|
|
9
|
+
from .global_values import GlobalValuesGet, CompanyGlobalValueCreate, CompanyGlobalValueResponse, CompanyGlobalValueUpdate, GlobalValueAssign, AssignedGlobalValuesGet
|
|
10
|
+
from .global_value_sets import GlobalValueSetsGet, GlobalValueSetCreate, GlobalValueSetUpdate, GlobalValueSetEmployeeAssignment, GlobalValueSetEmployeeAssignmentResponse
|
|
11
|
+
from .employee_pay_checks import PayChecksGet, PaycheckCreate, PaycheckUpdate
|
|
12
|
+
from .payrolls import PayrollsGet
|
|
13
|
+
from .payslips import PayslipsGet
|
|
14
|
+
from .supplements_and_deductions_rates import SupplementRatesGet, SupplementRegistrationsGet
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
'AbsenceGet', 'CreateAbsenceRequest', 'UpdateAbsenceRequest',
|
|
18
|
+
'CompaniesGet',
|
|
19
|
+
'CostCentersGet', 'CostCenterCreate',
|
|
20
|
+
'DepartmentsGet',
|
|
21
|
+
'EmployeesGet', 'EmployeesGetById', 'EmployeeCreate', 'EmployeeUpsert', 'EmployeeUpdate',
|
|
22
|
+
'PensionGet', 'EmployeePensionCreate',
|
|
23
|
+
'SupplementRegistrationsGet',
|
|
24
|
+
'GlobalValuesGet', 'CompanyGlobalValueCreate', 'CompanyGlobalValueResponse', 'CompanyGlobalValueUpdate', 'GlobalValueAssign', 'AssignedGlobalValuesGet',
|
|
25
|
+
'GlobalValueSetsGet', 'GlobalValueSetCreate', 'GlobalValueSetUpdate', 'GlobalValueSetEmployeeAssignment', 'GlobalValueSetEmployeeAssignmentResponse',
|
|
26
|
+
'PayChecksGet', 'PaycheckCreate', 'PaycheckUpdate',
|
|
27
|
+
'PayrollsGet',
|
|
28
|
+
'PayslipsGet',
|
|
29
|
+
'SupplementRatesGet'
|
|
30
|
+
]
|