(20260119) Attendance now captures total hours, over-time hours, first in time, and last out time.
This commit is contained in:
+12
-2
@@ -276,7 +276,7 @@ def sync_teams_to_tcaoff(
|
||||
role = (cosec_team.get("Grade Name") or "Unknown").strip(),
|
||||
username = tcaoff_username,
|
||||
password = "Vispl@123",
|
||||
application_notes = {"cosec": cosec_team}
|
||||
applicant_notes = {"cosec": cosec_team}
|
||||
)
|
||||
# response["total"] += 1
|
||||
if success: response["success"] += 1
|
||||
@@ -397,6 +397,10 @@ def sync_attendance_to_tcaoff(
|
||||
"work_date": last_dt
|
||||
}
|
||||
|
||||
# Add fixed known details:
|
||||
user_id_to_time[user_id]["first_in"] = first_in
|
||||
user_id_to_time[user_id]["last_out"] = last_out
|
||||
|
||||
print("\n")
|
||||
print("Result:")
|
||||
print("------")
|
||||
@@ -448,7 +452,7 @@ def sync_attendance_to_tcaoff(
|
||||
continue
|
||||
|
||||
# Update the attendance on TCAOFF:
|
||||
hours_worked = work["work_seconds"] / (60 * 60)
|
||||
hours_worked = work["work_seconds"] // (60 * 60)
|
||||
if hours_worked > 10.0: status = "OT"
|
||||
elif 7.5 < hours_worked <= 10.0: status = "P"
|
||||
elif 2.5 < hours_worked <= 5.0: status = "H"
|
||||
@@ -460,6 +464,11 @@ def sync_attendance_to_tcaoff(
|
||||
status = status,
|
||||
over_time = max(0.0, hours_worked - 10.0),
|
||||
attendance_date = work["work_date"],
|
||||
json_notes = {
|
||||
"totHours": hours_worked,
|
||||
"firstIn": work["first_in"],
|
||||
"lastOut": work["last_out"],
|
||||
}
|
||||
)
|
||||
if success: response["success"] += 1
|
||||
else: response["fail"] += 1
|
||||
@@ -935,6 +944,7 @@ if __name__ == "__main__":
|
||||
"deptAdd": "https://api.thecaoffice.com/commons/departments/add",
|
||||
"teamList": "https://api.thecaoffice.com/team/list",
|
||||
"teamAdd": "https://api.thecaoffice.com/team/add",
|
||||
"teamUpdate": "https://api.thecaoffice.com/team/update",
|
||||
"attendanceList": "https://api.thecaoffice.com/user/attendance/register",
|
||||
"attendanceMark": "https://api.thecaoffice.com/user/attendance/mark"
|
||||
}
|
||||
|
||||
+77
-6
@@ -376,7 +376,7 @@ def team_add(
|
||||
role: str,
|
||||
username: str,
|
||||
password: str,
|
||||
application_notes: dict | list | str = None
|
||||
applicant_notes: dict | list | str = None
|
||||
) -> bool:
|
||||
|
||||
"""
|
||||
@@ -391,13 +391,13 @@ def team_add(
|
||||
:param role: The role of the team member in the organization.
|
||||
:param username: The unique username of the team member. Cannot be the same as anyone else.
|
||||
:param password: The password for this team member's login.
|
||||
:param application_notes: Optional notes about the team member.
|
||||
:param applicant_notes: Optional notes about the team member.
|
||||
:return: True if successful, else False.
|
||||
"""
|
||||
|
||||
# Ensure that JSON notes are converted to string:
|
||||
if isinstance(application_notes, (list, dict)):
|
||||
application_notes = json.to_string(application_notes, no_space = True)
|
||||
# # Ensure that JSON notes are converted to string:
|
||||
# if isinstance(applicant_notes, (list, dict)):
|
||||
# applicant_notes = json.to_string(applicant_notes, no_space = True)
|
||||
|
||||
# Make the API call:
|
||||
response = requests.post(
|
||||
@@ -414,7 +414,7 @@ def team_add(
|
||||
"username": username,
|
||||
"password": password,
|
||||
"hierarchy": 1,
|
||||
"applicantNotes": application_notes
|
||||
"applicantNotes": applicant_notes
|
||||
}
|
||||
)
|
||||
|
||||
@@ -437,12 +437,79 @@ def team_add(
|
||||
# ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def team_update(
|
||||
tcaoff_creds: dict,
|
||||
user_id: int,
|
||||
branch_id: int,
|
||||
dept_id: int,
|
||||
reporting_to: int | None,
|
||||
team_name: str,
|
||||
email: str,
|
||||
phone_no: str,
|
||||
role: str,
|
||||
applicant_notes: dict | list | str = None
|
||||
) -> bool:
|
||||
|
||||
"""
|
||||
Add a new team member.
|
||||
:param tcaoff_creds: The set of credentials to use with the API call.
|
||||
:param dept_id: The id of the department that this team member is working in.
|
||||
:param branch_id: The id of the branch that this team member is working in.
|
||||
:param reporting_to: The id of the senior to whom this team member will report.
|
||||
:param team_name: The name of the team member. This is the full display name. Can be the same as others.
|
||||
:param email: The email id of the team member.
|
||||
:param phone_no: The phone no. of the team member.
|
||||
:param role: The role of the team member in the organization.
|
||||
:param applicant_notes: Optional notes about the team member.
|
||||
:return: True if successful, else False.
|
||||
"""
|
||||
|
||||
# # Ensure that JSON notes are converted to string:
|
||||
# if isinstance(applicant_notes, (list, dict)):
|
||||
# applicant_notes = json.to_string(applicant_notes, no_space = True)
|
||||
|
||||
# Make the API call:
|
||||
response = requests.post(
|
||||
url = tcaoff_creds["urls"]["teamUpdate"],
|
||||
headers = {"X-Session-Token": tcaoff_creds["creds"]["sessionToken"]},
|
||||
json = {
|
||||
"branchId": branch_id,
|
||||
"idDepartment": dept_id,
|
||||
"reportingTo": reporting_to,
|
||||
"name": team_name,
|
||||
"email": email,
|
||||
"phoneNo": phone_no,
|
||||
"role": role,
|
||||
"applicantNotes": applicant_notes
|
||||
}
|
||||
)
|
||||
|
||||
# Debugging:
|
||||
if response.status_code not in [200]:
|
||||
response_json = response.json()
|
||||
print("TCAOFF Team-Update:", json.to_string(response_json))
|
||||
|
||||
# If the call succeeded:
|
||||
if response.status_code in [200]:
|
||||
print(f"TCAOFF: team '{user_id}' updated")
|
||||
return True
|
||||
|
||||
# If the call failed:
|
||||
else:
|
||||
print(f"TCAOFF: team '{user_id}' NOT updated")
|
||||
return False
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def attendance_mark(
|
||||
tcaoff_creds: dict,
|
||||
user_id: int,
|
||||
status: Literal["P", "H", "A", "OT"],
|
||||
over_time: int | float,
|
||||
attendance_date: datetime.datetime | None = None,
|
||||
json_notes: dict = None
|
||||
) -> bool:
|
||||
|
||||
"""
|
||||
@@ -470,6 +537,10 @@ def attendance_mark(
|
||||
"ot": over_time,
|
||||
}
|
||||
|
||||
# Add JSON notes is needed:
|
||||
if json_notes:
|
||||
json_payload["jsonNotes"] = json_notes
|
||||
|
||||
# Make the API call:
|
||||
response = requests.post(
|
||||
url = tcaoff_creds["urls"]["attendanceMark"],
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,49 @@
|
||||
"""
|
||||
This is a one-time fix script where we need to fix some content of the accounts created.
|
||||
"""
|
||||
|
||||
# Imports:
|
||||
import os
|
||||
import pandas as pd
|
||||
from helpers import tcaoff
|
||||
from utils_v2.string import json
|
||||
from utils_v2.system import files
|
||||
|
||||
# File paths:
|
||||
file_dir = files.get_file_directory(include_filename = False)
|
||||
proj_dir = files.get_parent_directory(file_dir, depth = 1)
|
||||
tcaoff_creds_file = os.path.join(proj_dir, "creds", "tcaoff.json")
|
||||
|
||||
# Load the creds:
|
||||
tcaoff_creds = json.from_file(tcaoff_creds_file)
|
||||
|
||||
# Log in:
|
||||
tcaoff.login(tcaoff_creds)
|
||||
|
||||
# Load the team list:
|
||||
team_list = tcaoff.team_list(tcaoff_creds)
|
||||
|
||||
# Loop through the list,
|
||||
# check if `applicantNotes` in `json_notes` is a string,
|
||||
# if it is a string, convert it to a dict/list and update the user:
|
||||
for team in team_list:
|
||||
|
||||
# Extract info:
|
||||
json_notes = json.from_string(team.get("json_notes", {}))
|
||||
app_notes = json_notes.get("applicantNotes")
|
||||
|
||||
# If the app notes are a string, update them:
|
||||
if isinstance(app_notes, str):
|
||||
app_notes = json.from_string(app_notes)
|
||||
json_notes["applicantNotes"] = app_notes
|
||||
team["json_notes"] = json.to_string(json_notes, no_space = True)
|
||||
|
||||
# Make a pandas DataFrame:
|
||||
team_df = pd.DataFrame(team_list)
|
||||
|
||||
# Log out:
|
||||
tcaoff.logout(tcaoff_creds)
|
||||
|
||||
# Show and save the DF:
|
||||
print(team_df[:10].to_string())
|
||||
team_df[["user_id", "json_notes"]].to_csv(r"C:\Users\Khushal P Soonderji\Downloads\20260116_cosec_team_fix.csv", index = False)
|
||||
Reference in New Issue
Block a user