brynq-sdk-sage-100-france 1.2.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.
- brynq_sdk_sage_100_france/__init__.py +1 -0
- brynq_sdk_sage_100_france/absence.py +35 -0
- brynq_sdk_sage_100_france/address.py +38 -0
- brynq_sdk_sage_100_france/bank_info.py +40 -0
- brynq_sdk_sage_100_france/company.py +42 -0
- brynq_sdk_sage_100_france/contract.py +37 -0
- brynq_sdk_sage_100_france/department.py +36 -0
- brynq_sdk_sage_100_france/employee.py +255 -0
- brynq_sdk_sage_100_france/employee_insurance.py +40 -0
- brynq_sdk_sage_100_france/event.py +30 -0
- brynq_sdk_sage_100_france/family.py +38 -0
- brynq_sdk_sage_100_france/insurance.py +39 -0
- brynq_sdk_sage_100_france/leave.py +35 -0
- brynq_sdk_sage_100_france/position.py +38 -0
- brynq_sdk_sage_100_france/sage_100_france.py +297 -0
- brynq_sdk_sage_100_france/salary.py +41 -0
- brynq_sdk_sage_100_france/schemas/__init__.py +70 -0
- brynq_sdk_sage_100_france/schemas/absence.py +41 -0
- brynq_sdk_sage_100_france/schemas/address.py +49 -0
- brynq_sdk_sage_100_france/schemas/bank_info.py +59 -0
- brynq_sdk_sage_100_france/schemas/company.py +45 -0
- brynq_sdk_sage_100_france/schemas/contract.py +64 -0
- brynq_sdk_sage_100_france/schemas/department.py +31 -0
- brynq_sdk_sage_100_france/schemas/employee.py +349 -0
- brynq_sdk_sage_100_france/schemas/employee_insurance.py +52 -0
- brynq_sdk_sage_100_france/schemas/event.py +58 -0
- brynq_sdk_sage_100_france/schemas/family.py +47 -0
- brynq_sdk_sage_100_france/schemas/insurance.py +37 -0
- brynq_sdk_sage_100_france/schemas/leave.py +37 -0
- brynq_sdk_sage_100_france/schemas/position.py +41 -0
- brynq_sdk_sage_100_france/schemas/salary.py +318 -0
- brynq_sdk_sage_100_france/schemas/service.py +31 -0
- brynq_sdk_sage_100_france/schemas/work.py +178 -0
- brynq_sdk_sage_100_france/service.py +35 -0
- brynq_sdk_sage_100_france/test_excel_import.py +159 -0
- brynq_sdk_sage_100_france/work.py +49 -0
- brynq_sdk_sage_100_france-1.2.1.dist-info/METADATA +16 -0
- brynq_sdk_sage_100_france-1.2.1.dist-info/RECORD +40 -0
- brynq_sdk_sage_100_france-1.2.1.dist-info/WHEEL +5 -0
- brynq_sdk_sage_100_france-1.2.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .sage_100_france import Sage100France
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from .schemas.absence import AbsenceSchema
|
|
3
|
+
from brynq_sdk_functions import Functions
|
|
4
|
+
|
|
5
|
+
class Absence:
|
|
6
|
+
"""Class for interacting with Sage 100 France absence endpoints"""
|
|
7
|
+
|
|
8
|
+
# Get column names from schema
|
|
9
|
+
COLUMN_NAMES = list(AbsenceSchema.to_schema().columns.keys())
|
|
10
|
+
|
|
11
|
+
def __init__(self, sage_100_france):
|
|
12
|
+
"""Initialize Absence class
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
sage_100_france: Parent Sage 100 France instance for authentication and configuration
|
|
16
|
+
"""
|
|
17
|
+
self.sage_100_france = sage_100_france
|
|
18
|
+
self.db_table = "T_MOTIFDABSENCE"
|
|
19
|
+
|
|
20
|
+
def get(self):
|
|
21
|
+
"""Get all absence records
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
pandas.DataFrame: DataFrame containing absence data with schema validation
|
|
25
|
+
"""
|
|
26
|
+
absence = self.sage_100_france.get(table_name=self.db_table, columns=self.COLUMN_NAMES)
|
|
27
|
+
try:
|
|
28
|
+
df = pd.DataFrame(absence)
|
|
29
|
+
if not df.empty:
|
|
30
|
+
df.columns = self.COLUMN_NAMES
|
|
31
|
+
valid_data, invalid_data = Functions.validate_data(df, AbsenceSchema)
|
|
32
|
+
return valid_data, invalid_data
|
|
33
|
+
return df
|
|
34
|
+
except Exception as e:
|
|
35
|
+
raise ValueError(f"There was an error processing the Absence data: {e}")
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from .schemas.address import AddressSchema
|
|
3
|
+
from brynq_sdk_functions import Functions
|
|
4
|
+
|
|
5
|
+
class Address:
|
|
6
|
+
"""Class for interacting with Sage 100 France address history endpoints"""
|
|
7
|
+
|
|
8
|
+
# Get column names from schema
|
|
9
|
+
COLUMN_NAMES = list(AddressSchema.to_schema().columns.keys())
|
|
10
|
+
|
|
11
|
+
def __init__(self, sage_100_france):
|
|
12
|
+
"""Initialize Address class
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
sage_100_france: Parent Sage 100 France instance for authentication and configuration
|
|
16
|
+
"""
|
|
17
|
+
self.sage_100_france = sage_100_france
|
|
18
|
+
self.db_table = "T_HST_ADRESSE"
|
|
19
|
+
|
|
20
|
+
def get(self):
|
|
21
|
+
"""Get all address history records
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
pandas.DataFrame: DataFrame containing address history data with schema validation
|
|
25
|
+
|
|
26
|
+
Raises:
|
|
27
|
+
ValueError: If there is an error processing the address data
|
|
28
|
+
"""
|
|
29
|
+
address = self.sage_100_france.get(table_name=self.db_table, columns=self.COLUMN_NAMES)
|
|
30
|
+
try:
|
|
31
|
+
df = pd.DataFrame(address)
|
|
32
|
+
if not df.empty:
|
|
33
|
+
df.columns = self.COLUMN_NAMES
|
|
34
|
+
valid_data, invalid_data = Functions.validate_data(df, AddressSchema)
|
|
35
|
+
return valid_data, invalid_data
|
|
36
|
+
return df
|
|
37
|
+
except Exception as e:
|
|
38
|
+
raise ValueError(f"There was an error processing the Address data: {e}")
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from brynq_sdk_functions import Functions
|
|
3
|
+
|
|
4
|
+
from .schemas.bank_info import BankInfoSchema
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BankInfo:
|
|
8
|
+
"""Class for interacting with Sage 100 France bank information endpoints"""
|
|
9
|
+
|
|
10
|
+
# Get column names from schema
|
|
11
|
+
COLUMN_NAMES = list(BankInfoSchema.to_schema().columns.keys())
|
|
12
|
+
|
|
13
|
+
def __init__(self, sage_100_france):
|
|
14
|
+
"""Initialize BankInfo class
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
sage_100_france: Parent Sage 100 France instance for authentication and configuration
|
|
18
|
+
"""
|
|
19
|
+
self.sage_100_france = sage_100_france
|
|
20
|
+
self.db_table = "T_INFOBANQUE"
|
|
21
|
+
|
|
22
|
+
def get(self):
|
|
23
|
+
"""Get all bank information records
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
pandas.DataFrame: DataFrame containing bank information data with schema validation
|
|
27
|
+
|
|
28
|
+
Raises:
|
|
29
|
+
ValueError: If there is an error processing the bank information data
|
|
30
|
+
"""
|
|
31
|
+
bank_info = self.sage_100_france.get(table_name=self.db_table, columns=self.COLUMN_NAMES)
|
|
32
|
+
try:
|
|
33
|
+
df = pd.DataFrame(bank_info)
|
|
34
|
+
if not df.empty:
|
|
35
|
+
df.columns = self.COLUMN_NAMES
|
|
36
|
+
valid_data, invalid_data = Functions.validate_data(df, BankInfoSchema)
|
|
37
|
+
return valid_data, invalid_data
|
|
38
|
+
return df
|
|
39
|
+
except Exception as e:
|
|
40
|
+
raise ValueError(f"There was an error processing the Bank Info data: {e}")
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
import pandera as pa
|
|
3
|
+
from pandera.typing import Series
|
|
4
|
+
from typing import Union, List, Dict, Any
|
|
5
|
+
from .schemas.company import CompanySchema
|
|
6
|
+
from brynq_sdk_functions import Functions
|
|
7
|
+
|
|
8
|
+
class Company:
|
|
9
|
+
"""Class for interacting with Sage 100 France company endpoints"""
|
|
10
|
+
|
|
11
|
+
# Get column names from schema
|
|
12
|
+
COLUMN_NAMES = list(CompanySchema.to_schema().columns.keys())
|
|
13
|
+
|
|
14
|
+
def __init__(self, sage_100_france):
|
|
15
|
+
"""Initialize Company class
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
sage_100_france: Parent Sage 100 France instance for authentication and configuration
|
|
19
|
+
"""
|
|
20
|
+
self.sage_100_france = sage_100_france
|
|
21
|
+
self.db_table = "T_SOCIETE"
|
|
22
|
+
|
|
23
|
+
def get(self):
|
|
24
|
+
"""Get company information
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
pandas.DataFrame: DataFrame containing company data with schema validation
|
|
28
|
+
|
|
29
|
+
Raises:
|
|
30
|
+
ValueError: If there is an error processing the company data
|
|
31
|
+
"""
|
|
32
|
+
company = self.sage_100_france.get(table_name=self.db_table, columns=self.COLUMN_NAMES)
|
|
33
|
+
try:
|
|
34
|
+
df = pd.DataFrame(company)
|
|
35
|
+
if not df.empty:
|
|
36
|
+
df.columns = self.COLUMN_NAMES
|
|
37
|
+
valid_data, invalid_data = Functions.validate_data(df, CompanySchema)
|
|
38
|
+
return valid_data, invalid_data
|
|
39
|
+
return df
|
|
40
|
+
except Exception as e:
|
|
41
|
+
raise ValueError(f"There was an error processing the Company data: {e}")
|
|
42
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from .schemas.contract import ContractSchema
|
|
3
|
+
from brynq_sdk_functions import Functions
|
|
4
|
+
|
|
5
|
+
class Contract:
|
|
6
|
+
"""Class for interacting with Sage 100 France contract endpoints"""
|
|
7
|
+
|
|
8
|
+
# Get column names from schema
|
|
9
|
+
COLUMN_NAMES = list(ContractSchema.to_schema().columns.keys())
|
|
10
|
+
|
|
11
|
+
def __init__(self, sage_100_france):
|
|
12
|
+
"""Initialize Contract class
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
sage_100_france: Parent Sage 100 France instance for authentication and configuration
|
|
16
|
+
"""
|
|
17
|
+
self.sage_100_france = sage_100_france
|
|
18
|
+
self.db_table = "T_HST_CONTRAT"
|
|
19
|
+
|
|
20
|
+
def get(self):
|
|
21
|
+
"""Get all contract records
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
pandas.DataFrame: DataFrame containing contract data with schema validation
|
|
25
|
+
|
|
26
|
+
Raises:
|
|
27
|
+
ValueError: If there is an error processing the contract data
|
|
28
|
+
"""
|
|
29
|
+
contract = self.sage_100_france.get(table_name=self.db_table, columns=self.COLUMN_NAMES)
|
|
30
|
+
try:
|
|
31
|
+
df = pd.DataFrame(contract)
|
|
32
|
+
if not df.empty:
|
|
33
|
+
df.columns = self.COLUMN_NAMES
|
|
34
|
+
valid_data, = Functions.validate_data(df, ContractSchema)
|
|
35
|
+
return valid_data
|
|
36
|
+
except Exception as e:
|
|
37
|
+
raise ValueError(f"There was an error processing the Contract data: {e}")
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from typing import Union, List, Dict, Any
|
|
3
|
+
from .schemas.department import DepartmentSchema
|
|
4
|
+
from brynq_sdk_functions import Functions
|
|
5
|
+
|
|
6
|
+
class Department:
|
|
7
|
+
"""Class for interacting with Sage 100 France department endpoints"""
|
|
8
|
+
|
|
9
|
+
# Get column names from schema
|
|
10
|
+
COLUMN_NAMES = list(DepartmentSchema.to_schema().columns.keys())
|
|
11
|
+
|
|
12
|
+
def __init__(self, sage_100_france):
|
|
13
|
+
"""Initialize Department class
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
sage_100_france: Parent Sage 100 France instance for authentication and configuration
|
|
17
|
+
"""
|
|
18
|
+
self.sage_100_france = sage_100_france
|
|
19
|
+
self.db_table = "T_DEPARTEMENT"
|
|
20
|
+
|
|
21
|
+
def get(self):
|
|
22
|
+
"""Get all department records
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
pandas.DataFrame: DataFrame containing department data with schema validation
|
|
26
|
+
"""
|
|
27
|
+
department = self.sage_100_france.get(table_name=self.db_table, columns=self.COLUMN_NAMES)
|
|
28
|
+
try:
|
|
29
|
+
df = pd.DataFrame(department)
|
|
30
|
+
if not df.empty:
|
|
31
|
+
df.columns = self.COLUMN_NAMES
|
|
32
|
+
valid_data, invalid_data = Functions.validate_data(df, DepartmentSchema)
|
|
33
|
+
return valid_data, invalid_data
|
|
34
|
+
except Exception as e:
|
|
35
|
+
raise ValueError(f"There was an error processing the Department data: {e}")
|
|
36
|
+
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from typing import Dict, Any, Type
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
from brynq_sdk_functions import Functions
|
|
5
|
+
from .schemas.employee import EmployeeSchema, EmployeeExcelImport
|
|
6
|
+
from .schemas.employee import PersonnelRecordTimePageSchema
|
|
7
|
+
from .schemas.employee import RegistrationSchema
|
|
8
|
+
from .schemas.employee import CivilStatusSchema
|
|
9
|
+
from .schemas.employee import DadsUSchema
|
|
10
|
+
from .work import Work
|
|
11
|
+
from .employee_insurance import EmployeeInsurance
|
|
12
|
+
class Employee:
|
|
13
|
+
"""Class for interacting with Sage 100 France employee endpoints"""
|
|
14
|
+
|
|
15
|
+
# Get column names from schema
|
|
16
|
+
COLUMN_NAMES = list(EmployeeSchema.to_schema().columns.keys())
|
|
17
|
+
|
|
18
|
+
def __init__(self, sage_100_france):
|
|
19
|
+
"""Initialize Employees class
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
sage_100_france: Parent Sage 100 France instance for authentication and configuration
|
|
23
|
+
"""
|
|
24
|
+
self.sage_100_france = sage_100_france
|
|
25
|
+
self.work = Work(self)
|
|
26
|
+
self.insurance = EmployeeInsurance(self)
|
|
27
|
+
self.db_table = "T_CONTACT"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def get(self):
|
|
32
|
+
"""Get all employees
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
pandas.DataFrame: DataFrame containing employee data with schema validation
|
|
36
|
+
|
|
37
|
+
Raises:
|
|
38
|
+
ValueError: If there is an error processing the employee data
|
|
39
|
+
"""
|
|
40
|
+
employee = self.sage_100_france.get(table_name=self.db_table, columns=self.COLUMN_NAMES)
|
|
41
|
+
try:
|
|
42
|
+
df = pd.DataFrame(employee)
|
|
43
|
+
if not df.empty:
|
|
44
|
+
df.columns = self.COLUMN_NAMES
|
|
45
|
+
valid_data, invalid_data = Functions.validate_data(df, EmployeeSchema)
|
|
46
|
+
return valid_data, invalid_data
|
|
47
|
+
return df
|
|
48
|
+
except Exception as e:
|
|
49
|
+
raise ValueError(f"There was an error processing the Employee data: {e}")
|
|
50
|
+
|
|
51
|
+
def import_registration_data(self, df: pd.DataFrame):
|
|
52
|
+
"""
|
|
53
|
+
Import registration data
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
df: DataFrame to import
|
|
57
|
+
"""
|
|
58
|
+
# Add unique_code automatically - it's always "01" for Registration
|
|
59
|
+
df = df.copy()
|
|
60
|
+
df['unique_code'] = "01"
|
|
61
|
+
|
|
62
|
+
valid_data = RegistrationSchema(df)
|
|
63
|
+
|
|
64
|
+
rows = self.sage_100_france.prepare_formatted_rows(df=valid_data, schema=RegistrationSchema)
|
|
65
|
+
|
|
66
|
+
self.sage_100_france.add_rows_to_buffer(rows)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def export_to_excel(
|
|
70
|
+
self,
|
|
71
|
+
df: pd.DataFrame,
|
|
72
|
+
output_excel_path: str,
|
|
73
|
+
schema: Type[BaseModel] = EmployeeExcelImport
|
|
74
|
+
):
|
|
75
|
+
"""
|
|
76
|
+
Validate employee DataFrame with Pydantic schema and export to Excel.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
df: pandas DataFrame with employee data
|
|
80
|
+
output_excel_path: Path to output Excel file
|
|
81
|
+
schema: Pydantic BaseModel schema for validation (default: EmployeeExcelImport)
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
Tuple of (validated_df, error_count)
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
# Warning for custom schemas
|
|
88
|
+
if schema != EmployeeExcelImport:
|
|
89
|
+
print("⚠ WARNING: Using custom schema.")
|
|
90
|
+
print("⚠ For Sage 100 France import Excel:")
|
|
91
|
+
print("⚠ Field order in schema MUST match EXACTLY the format definition.")
|
|
92
|
+
print("⚠ Fields must be defined in schema in the same order as in the format.")
|
|
93
|
+
print()
|
|
94
|
+
|
|
95
|
+
records = df.to_dict("records")
|
|
96
|
+
|
|
97
|
+
validated_rows = []
|
|
98
|
+
error_count = 0
|
|
99
|
+
|
|
100
|
+
for i, rec in enumerate(records, start=1):
|
|
101
|
+
try:
|
|
102
|
+
m = schema.model_validate(rec)
|
|
103
|
+
validated_rows.append(m.model_dump(by_alias=True))
|
|
104
|
+
except Exception as e:
|
|
105
|
+
print(f"✗ Row {i} validation error: {e}")
|
|
106
|
+
error_count += 1
|
|
107
|
+
|
|
108
|
+
if not validated_rows:
|
|
109
|
+
raise ValueError("No valid rows found in data")
|
|
110
|
+
|
|
111
|
+
validated_df = pd.DataFrame(validated_rows)
|
|
112
|
+
validated_df.to_excel(output_excel_path, index=False, sheet_name="Employees")
|
|
113
|
+
|
|
114
|
+
print(f"✓ Validated {len(validated_rows)} rows successfully")
|
|
115
|
+
if error_count:
|
|
116
|
+
print(f"✗ {error_count} rows had validation errors")
|
|
117
|
+
|
|
118
|
+
return output_excel_path
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _generate_child_field_specs(self, max_children: int) -> dict:
|
|
123
|
+
"""
|
|
124
|
+
Generate field specifications for child data dynamically.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
max_children: Maximum number of children to support
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
Dictionary with child field specifications
|
|
131
|
+
"""
|
|
132
|
+
child_specs = {}
|
|
133
|
+
|
|
134
|
+
# Starting position for first child (after number_of_children field)
|
|
135
|
+
base_position = 364
|
|
136
|
+
|
|
137
|
+
for child_num in range(1, max_children + 1):
|
|
138
|
+
# Each child takes 62 positions (2+20+30+8+1+1)
|
|
139
|
+
child_base_pos = base_position + ((child_num - 1) * 62)
|
|
140
|
+
|
|
141
|
+
child_specs.update({
|
|
142
|
+
f'child_{child_num}_number': {'position': child_base_pos, 'length': 2},
|
|
143
|
+
f'child_{child_num}_first_name': {'position': child_base_pos + 2, 'length': 20},
|
|
144
|
+
f'child_{child_num}_last_name': {'position': child_base_pos + 22, 'length': 30},
|
|
145
|
+
f'child_{child_num}_birth_date': {'position': child_base_pos + 52, 'length': 8},
|
|
146
|
+
f'child_{child_num}_gender': {'position': child_base_pos + 60, 'length': 1},
|
|
147
|
+
f'child_{child_num}_dependent': {'position': child_base_pos + 61, 'length': 1},
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
return child_specs
|
|
151
|
+
|
|
152
|
+
def _fill_missing_child_data(self, df: pd.DataFrame, max_children: int = 100) -> pd.DataFrame:
|
|
153
|
+
"""
|
|
154
|
+
Fill missing child data with default values for up to max_children.
|
|
155
|
+
|
|
156
|
+
For each child that doesn't exist in the data, fill with:
|
|
157
|
+
- child_X_number: 0
|
|
158
|
+
- child_X_first_name: ""
|
|
159
|
+
- child_X_last_name: ""
|
|
160
|
+
- child_X_birth_date: ""
|
|
161
|
+
- child_X_gender: 0
|
|
162
|
+
- child_X_dependent: 0
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
df: DataFrame with child data
|
|
166
|
+
max_children: Maximum number of children to support
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
DataFrame with all child fields filled
|
|
170
|
+
"""
|
|
171
|
+
df = df.copy()
|
|
172
|
+
|
|
173
|
+
# Define default values for missing child data
|
|
174
|
+
child_defaults = {
|
|
175
|
+
'number': 0, # Numeric field
|
|
176
|
+
'first_name': "",
|
|
177
|
+
'last_name': "",
|
|
178
|
+
'birth_date': "",
|
|
179
|
+
'gender': 0, # Numeric field (0 = not specified)
|
|
180
|
+
'dependent': 0 # Numeric field (0 = not dependent)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
# Collect all missing columns and their default values
|
|
184
|
+
missing_columns = {}
|
|
185
|
+
|
|
186
|
+
# Check for missing child columns (1 to max_children)
|
|
187
|
+
for child_num in range(1, max_children + 1):
|
|
188
|
+
for field, default_value in child_defaults.items():
|
|
189
|
+
column_name = f"child_{child_num}_{field}"
|
|
190
|
+
if column_name not in df.columns:
|
|
191
|
+
# Column doesn't exist, add to missing columns
|
|
192
|
+
missing_columns[column_name] = [default_value] * len(df)
|
|
193
|
+
else:
|
|
194
|
+
# Column exists but may have NaN values, fill them
|
|
195
|
+
df[column_name] = df[column_name].fillna(default_value)
|
|
196
|
+
|
|
197
|
+
# Add all missing columns at once using pd.concat for better performance
|
|
198
|
+
if missing_columns:
|
|
199
|
+
missing_df = pd.DataFrame(missing_columns, index=df.index)
|
|
200
|
+
df = pd.concat([df, missing_df], axis=1)
|
|
201
|
+
|
|
202
|
+
return df
|
|
203
|
+
|
|
204
|
+
def import_civil_status_data(self, df: pd.DataFrame):
|
|
205
|
+
"""
|
|
206
|
+
Import civil status data
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
df: DataFrame to import
|
|
210
|
+
"""
|
|
211
|
+
# Add unique_code automatically - it's always "02" for Civil Status
|
|
212
|
+
df = df.copy()
|
|
213
|
+
df['unique_code'] = "02"
|
|
214
|
+
|
|
215
|
+
df = self._fill_missing_child_data(df, max_children=99)
|
|
216
|
+
|
|
217
|
+
valid_data = CivilStatusSchema(df)
|
|
218
|
+
|
|
219
|
+
rows = self.sage_100_france.prepare_formatted_rows(df=valid_data, schema=CivilStatusSchema)
|
|
220
|
+
|
|
221
|
+
self.sage_100_france.add_rows_to_buffer(rows)
|
|
222
|
+
|
|
223
|
+
def import_time_page_data(self, df: pd.DataFrame):
|
|
224
|
+
"""
|
|
225
|
+
Import time page data
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
df: DataFrame to import
|
|
229
|
+
"""
|
|
230
|
+
# Add unique_code automatically - it's always "GT" for Time Page
|
|
231
|
+
df = df.copy()
|
|
232
|
+
df['unique_code'] = "GT"
|
|
233
|
+
|
|
234
|
+
valid_data = PersonnelRecordTimePageSchema(df)
|
|
235
|
+
|
|
236
|
+
rows = self.sage_100_france.prepare_formatted_rows(df=valid_data, schema=PersonnelRecordTimePageSchema)
|
|
237
|
+
|
|
238
|
+
self.sage_100_france.add_rows_to_buffer(rows)
|
|
239
|
+
|
|
240
|
+
def import_dads_u_data(self, df: pd.DataFrame):
|
|
241
|
+
"""
|
|
242
|
+
Import DADS-U (Données DADS-U) data
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
df: DataFrame to import
|
|
246
|
+
"""
|
|
247
|
+
# Add unique_code automatically - it's always "DU" for DADS-U
|
|
248
|
+
df = df.copy()
|
|
249
|
+
df['unique_code'] = "DU"
|
|
250
|
+
|
|
251
|
+
valid_data = DadsUSchema(df)
|
|
252
|
+
|
|
253
|
+
rows = self.sage_100_france.prepare_formatted_rows(df=valid_data, schema=DadsUSchema)
|
|
254
|
+
|
|
255
|
+
self.sage_100_france.add_rows_to_buffer(rows)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from typing import Union, List, Dict, Any
|
|
3
|
+
from .schemas.employee_insurance import EmployeeInsuranceSchema
|
|
4
|
+
from brynq_sdk_functions import Functions
|
|
5
|
+
|
|
6
|
+
class EmployeeInsurance:
|
|
7
|
+
"""Class for interacting with Sage 100 France employee insurance affiliations"""
|
|
8
|
+
|
|
9
|
+
# Get column names from schema
|
|
10
|
+
COLUMN_NAMES = list(EmployeeInsuranceSchema.to_schema().columns.keys())
|
|
11
|
+
|
|
12
|
+
def __init__(self, employee):
|
|
13
|
+
"""Initialize EmployeeInsurance class
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
sage_100_france: Parent Sage 100 France instance for authentication and configuration
|
|
17
|
+
"""
|
|
18
|
+
self.employee = employee
|
|
19
|
+
self.db_table = "T_SALARIE_CONTRAT_SOCIAL"
|
|
20
|
+
|
|
21
|
+
def get(self):
|
|
22
|
+
"""Get all employee insurance affiliation records
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
pandas.DataFrame: DataFrame containing employee insurance data with schema validation
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
ValueError: If there is an error processing the employee insurance data
|
|
29
|
+
"""
|
|
30
|
+
employee_insurance = self.employee.sage_100_france.get(table_name=self.db_table, columns=self.COLUMN_NAMES)
|
|
31
|
+
try:
|
|
32
|
+
df = pd.DataFrame(employee_insurance)
|
|
33
|
+
if not df.empty:
|
|
34
|
+
df.columns = self.COLUMN_NAMES
|
|
35
|
+
valid_data, invalid_data = Functions.validate_data(df, EmployeeInsuranceSchema)
|
|
36
|
+
return valid_data, invalid_data
|
|
37
|
+
return df
|
|
38
|
+
except Exception as e:
|
|
39
|
+
raise ValueError(f"There was an error processing the Employee Insurance data: {e}")
|
|
40
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from .schemas.event import EventSchema
|
|
3
|
+
|
|
4
|
+
class Event:
|
|
5
|
+
"""Class for interacting with Sage 100 France event endpoints"""
|
|
6
|
+
|
|
7
|
+
def __init__(self, sage_100_france):
|
|
8
|
+
"""Initialize Event class
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
sage_100_france: Parent Sage 100 France instance for authentication and configuration
|
|
12
|
+
"""
|
|
13
|
+
self.sage_100_france = sage_100_france
|
|
14
|
+
|
|
15
|
+
def import_event_data(self, df: pd.DataFrame):
|
|
16
|
+
"""
|
|
17
|
+
Import event data
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
df: DataFrame to import
|
|
21
|
+
"""
|
|
22
|
+
# Add unique_code automatically - it's always "EV" for Event
|
|
23
|
+
df = df.copy()
|
|
24
|
+
df['unique_code'] = "EV"
|
|
25
|
+
|
|
26
|
+
valid_data = EventSchema(df)
|
|
27
|
+
|
|
28
|
+
rows = self.sage_100_france.prepare_formatted_rows(df=valid_data, schema=EventSchema)
|
|
29
|
+
|
|
30
|
+
self.sage_100_france.add_rows_to_buffer(rows)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from .schemas.family import FamilySchema
|
|
3
|
+
from brynq_sdk_functions import Functions
|
|
4
|
+
|
|
5
|
+
class Family:
|
|
6
|
+
"""Class for interacting with Sage 100 France family history endpoints"""
|
|
7
|
+
|
|
8
|
+
# Get column names from schema
|
|
9
|
+
COLUMN_NAMES = list(FamilySchema.to_schema().columns.keys())
|
|
10
|
+
|
|
11
|
+
def __init__(self, sage_100_france):
|
|
12
|
+
"""Initialize Family class
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
sage_100_france: Parent Sage 100 France instance for authentication and configuration
|
|
16
|
+
"""
|
|
17
|
+
self.sage_100_france = sage_100_france
|
|
18
|
+
self.db_table = "T_HST_FAMILLE"
|
|
19
|
+
|
|
20
|
+
def get(self):
|
|
21
|
+
"""Get all family history records
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
pandas.DataFrame: DataFrame containing family history data with schema validation
|
|
25
|
+
|
|
26
|
+
Raises:
|
|
27
|
+
ValueError: If there is an error processing the family data
|
|
28
|
+
"""
|
|
29
|
+
family = self.sage_100_france.get(table_name=self.db_table, columns=self.COLUMN_NAMES)
|
|
30
|
+
try:
|
|
31
|
+
df = pd.DataFrame(family)
|
|
32
|
+
if not df.empty:
|
|
33
|
+
df.columns = self.COLUMN_NAMES
|
|
34
|
+
valid_data, invalid_Data = Functions.validate_data(df, FamilySchema)
|
|
35
|
+
return valid_data, invalid_Data
|
|
36
|
+
return df
|
|
37
|
+
except Exception as e:
|
|
38
|
+
raise ValueError(f"There was an error processing the Family data: {e}")
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from typing import Union, List, Dict, Any
|
|
3
|
+
from .schemas.insurance import InsuranceSchema
|
|
4
|
+
from brynq_sdk_functions import Functions
|
|
5
|
+
|
|
6
|
+
class Insurance:
|
|
7
|
+
"""Class for interacting with Sage 100 France insurance endpoints"""
|
|
8
|
+
|
|
9
|
+
# Get column names from schema
|
|
10
|
+
COLUMN_NAMES = list(InsuranceSchema.to_schema().columns.keys())
|
|
11
|
+
|
|
12
|
+
def __init__(self, sage_100_france):
|
|
13
|
+
"""Initialize Insurance class
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
sage_100_france: Parent Sage 100 France instance for authentication and configuration
|
|
17
|
+
"""
|
|
18
|
+
self.sage_100_france = sage_100_france
|
|
19
|
+
self.db_table = "T_CONTRAT_SOCIAL"
|
|
20
|
+
|
|
21
|
+
def get(self):
|
|
22
|
+
"""Get all insurance records
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
pandas.DataFrame: DataFrame containing insurance data with schema validation
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
ValueError: If there is an error processing the insurance data
|
|
29
|
+
"""
|
|
30
|
+
insurance = self.sage_100_france.get(table_name=self.db_table, columns=self.COLUMN_NAMES)
|
|
31
|
+
try:
|
|
32
|
+
df = pd.DataFrame(insurance)
|
|
33
|
+
if not df.empty:
|
|
34
|
+
df.columns = self.COLUMN_NAMES
|
|
35
|
+
valid_data, invalid_data = Functions.validate_data(df, InsuranceSchema)
|
|
36
|
+
return valid_data, invalid_data
|
|
37
|
+
return df
|
|
38
|
+
except Exception as e:
|
|
39
|
+
raise ValueError(f"There was an error processing the Insrance data: {e}")
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from .schemas.leave import LeaveSchema
|
|
3
|
+
from brynq_sdk_functions import Functions
|
|
4
|
+
|
|
5
|
+
class Leave:
|
|
6
|
+
"""Class for interacting with Sage 100 France leave history endpoints"""
|
|
7
|
+
|
|
8
|
+
# Get column names from schema
|
|
9
|
+
COLUMN_NAMES = list(LeaveSchema.to_schema().columns.keys())
|
|
10
|
+
|
|
11
|
+
def __init__(self, sage_100_france):
|
|
12
|
+
"""Initialize Leave class
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
sage_100_france: Parent Sage 100 France instance for authentication and configuration
|
|
16
|
+
"""
|
|
17
|
+
self.sage_100_france = sage_100_france
|
|
18
|
+
self.db_table = "T_HST_CONGE"
|
|
19
|
+
|
|
20
|
+
def get(self):
|
|
21
|
+
"""Get all leave history records
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
pandas.DataFrame: DataFrame containing leave history data with schema validation
|
|
25
|
+
"""
|
|
26
|
+
leave = self.sage_100_france.get(table_name=self.db_table, columns=self.COLUMN_NAMES)
|
|
27
|
+
try:
|
|
28
|
+
df = pd.DataFrame(leave)
|
|
29
|
+
if not df.empty:
|
|
30
|
+
df.columns = self.COLUMN_NAMES
|
|
31
|
+
valid_data, invalid_data = Functions.validate_data(df, LeaveSchema)
|
|
32
|
+
return valid_data, invalid_data
|
|
33
|
+
return df
|
|
34
|
+
except Exception as e:
|
|
35
|
+
raise ValueError(f"There was an error processing the Leave data: {e}")
|