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.
Files changed (33) hide show
  1. brynq_sdk_zenegy/__init__.py +23 -0
  2. brynq_sdk_zenegy/absence.py +100 -0
  3. brynq_sdk_zenegy/companies.py +43 -0
  4. brynq_sdk_zenegy/cost_center.py +80 -0
  5. brynq_sdk_zenegy/departments.py +77 -0
  6. brynq_sdk_zenegy/employee_documents.py +40 -0
  7. brynq_sdk_zenegy/employees.py +301 -0
  8. brynq_sdk_zenegy/global_value_sets.py +260 -0
  9. brynq_sdk_zenegy/global_values.py +265 -0
  10. brynq_sdk_zenegy/paychecks.py +119 -0
  11. brynq_sdk_zenegy/payroll.py +117 -0
  12. brynq_sdk_zenegy/payslips.py +43 -0
  13. brynq_sdk_zenegy/pensions.py +118 -0
  14. brynq_sdk_zenegy/schemas/__init__.py +30 -0
  15. brynq_sdk_zenegy/schemas/absences.py +393 -0
  16. brynq_sdk_zenegy/schemas/companies.py +42 -0
  17. brynq_sdk_zenegy/schemas/company_cost_centers.py +48 -0
  18. brynq_sdk_zenegy/schemas/company_departments.py +147 -0
  19. brynq_sdk_zenegy/schemas/employee_documents.py +30 -0
  20. brynq_sdk_zenegy/schemas/employee_pay_checks.py +169 -0
  21. brynq_sdk_zenegy/schemas/employee_pensions.py +140 -0
  22. brynq_sdk_zenegy/schemas/employees.py +2372 -0
  23. brynq_sdk_zenegy/schemas/global_value_sets.py +185 -0
  24. brynq_sdk_zenegy/schemas/global_values.py +433 -0
  25. brynq_sdk_zenegy/schemas/payrolls.py +134 -0
  26. brynq_sdk_zenegy/schemas/payslips.py +32 -0
  27. brynq_sdk_zenegy/schemas/supplements_and_deductions_rates.py +189 -0
  28. brynq_sdk_zenegy/supplements_and_deductions_rates.py +71 -0
  29. brynq_sdk_zenegy/zenegy.py +221 -0
  30. brynq_sdk_zenegy-1.3.3.dist-info/METADATA +16 -0
  31. brynq_sdk_zenegy-1.3.3.dist-info/RECORD +33 -0
  32. brynq_sdk_zenegy-1.3.3.dist-info/WHEEL +5 -0
  33. 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
+ ]