Skip to content

Commit

Permalink
Initial commit with three project variants
Browse files Browse the repository at this point in the history
  • Loading branch information
“mil0sc” committed Feb 13, 2024
0 parents commit f612709
Show file tree
Hide file tree
Showing 55 changed files with 32,066 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions .idea/clock-in-out.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added csv-clock-in-out/.DS_Store
Binary file not shown.
8 changes: 8 additions & 0 deletions csv-clock-in-out/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions csv-clock-in-out/.idea/csv-clock-in-out.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions csv-clock-in-out/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions csv-clock-in-out/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file not shown.
Binary file not shown.
209 changes: 209 additions & 0 deletions csv-clock-in-out/clockInOutv2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import csv
import datetime
import logging


class TimesheetError(Exception):
"""Custom exception class for timesheet-related errors."""
pass


# Configure logging
logging.basicConfig(filename='timesheet.log', level=logging.INFO,
format='%(asctime)s:%(levelname)s:%(message)s')

# File name for CSV storage
timesheet_file = 'timesheet_data.csv'


def save_time_entry(employee_id, action):
# Validate employee_id and action
if not isinstance(employee_id, str) or not employee_id.strip():
raise ValueError("Invalid employee ID provided.")

valid_actions = ['IN', 'OUT']
if action not in valid_actions:
raise ValueError("Invalid action. Must be 'IN' or 'OUT'.")

try:
with open(timesheet_file, mode='a', newline='') as file:
writer = csv.writer(file)
writer.writerow([employee_id, datetime.datetime.now(), action])
except IOError as e:
logging.error(f"IOError while saving time entry: {e}")
raise TimesheetError("Failed to save time entry due to an internal error.")



def read_time_entries(employee_id):
try:
with open(timesheet_file, mode='r') as file:
reader = csv.reader(file)
return [row for row in reader if row[0] == employee_id]
except FileNotFoundError:
logging.error("Timesheet file not found.")
raise TimesheetError("Timesheet data is currently unavailable.")
except csv.Error as e:
logging.error(f"CSV error while reading time entries: {e}")
raise TimesheetError("Failed to read time entries due to a data error.")


def calculate_hours(employee_id):
entries = read_time_entries(employee_id)
total_seconds = 0
last_clock_in = None

for entry in entries:
try:
if len(entry) < 3 or not entry[0] == employee_id:
raise ValueError("Invalid entry format.")

time = datetime.datetime.fromisoformat(entry[1])
action = entry[2]

if action not in ['IN', 'OUT']:
raise ValueError("Invalid action in entry.")

# rest of the code...
except ValueError as e:
logging.error(f"Error processing time data for employee {employee_id}: {e}")
raise ValueError(f"Error processing time data for {employee_id}: {e}")

return total_seconds / 3600



def generate_report(employee_id=None):
"""
Generate a timesheet report for an employee or for all employees.
Only prints entries if they exist.
"""
if employee_id:
entries = read_time_entries(employee_id)
else:
with open(timesheet_file, mode='r') as file:
reader = csv.reader(file)
entries = list(reader)

if not entries: # Check if the entries list is empty
logging.info("No entries found for the report.")
return "No entries to report."

for entry in entries:
print(entry)


def does_employee_exist(employee_id):
try:
employee_id_lower = employee_id.lower()
with open('employees.csv', mode='r') as file:
reader = csv.reader(file)
for row in reader:
if row[0].lower() == employee_id_lower:
return True
return False
except FileNotFoundError:
raise FileNotFoundError("Employee file not found.")
except csv.Error as e:
raise Exception(f"Error reading employee file: {e}")


def last_employee_action(employee_id):
try:
entries = read_time_entries(employee_id)
if not entries:
return None
last_entry = entries[-1]
if len(last_entry) < 3 or last_entry[2] not in ['IN', 'OUT']:
raise ValueError("Invalid last entry format.")
return last_entry[2]
except ValueError as e:
logging.error(f"Error retrieving last action for employee {employee_id}: {e}")
raise



def get_employee_shift(employee_id):
"""Get the assigned shift for a given employee."""
try:
with open('employees.csv', mode='r') as file:
reader = csv.reader(file)
for row in reader:
if row[0].lower() == employee_id.lower():
return row[1].strip() # Extracts the shift, e.g., '(6-14)'
except Exception as e:
logging.error(f"Error reading employee file for employee {employee_id}: {e}")
raise Exception(f"Error reading employee file: {e}")


def is_within_shift(shift_hours, current_hour):
"""Check if the current hour is within the given shift hours."""
shift_times = {
'(6-14)': range(6, 14),
'(14-22)': range(14, 22),
'(22-6)': list(range(22, 24)) + list(range(0, 6))
}

is_within = current_hour in shift_times[shift_hours]

# Log the result of the check
logging.info(f"Checked shift {shift_hours} for hour {current_hour}: {'within' if is_within else 'outside'} shift")

return is_within


def clock_in(employee_id):
"""Clock in an employee if their shift matches the current time, and they are not already clocked in."""
last_action = last_employee_action(employee_id)

# Check if the employee is already clocked in
if last_action == 'IN':
raise ValueError(f"Employee {employee_id} is already clocked in.")

# Check if the employee exists and get their shift hours
shift_hours = get_employee_shift(employee_id)
if not shift_hours:
raise ValueError(f"Employee {employee_id} not found or shift not assigned.")

# Check if current time is within the employee's shift hours
current_hour = datetime.datetime.now().hour
if not is_within_shift(shift_hours, current_hour):
raise ValueError(f"Employee {employee_id} cannot clock in during this shift ({shift_hours}).")

# If all checks pass, save the time entry
save_time_entry(employee_id, 'IN')


def clock_out(employee_id):
save_time_entry(employee_id, 'OUT')


def try_clock_in(employee_id):
try:
clock_in(employee_id)
return "Success", f"Employee {employee_id} clocked in."
except ValueError as e:
logging.error(f"Clock-in error for employee {employee_id}: {e}")
return "Error", str(e)
except TimesheetError as e:
logging.error(f"Timesheet error during clock-in for employee {employee_id}: {e}")
return "Error", "An error occurred while clocking in."
except Exception as e:
logging.error(f"Unexpected error during clock-in for employee {employee_id}: {e}")
return "Error", "An unexpected error occurred: " + str(e)



def try_clock_out(employee_id):
try:
clock_out(employee_id)
return "Success", f"Employee {employee_id} clocked out."
except ValueError as e:
logging.error(f"Clock-out error for employee {employee_id}: {e}")
return "Error", str(e)
except TimesheetError as e:
logging.error(f"Timesheet error during clock-out for employee {employee_id}: {e}")
return "Error", "An error occurred while clocking out."
except Exception as e:
logging.error(f"Unexpected error during clock-out for employee {employee_id}: {e}")
return "Error", "An unexpected error occurred: " + str(e)
21 changes: 21 additions & 0 deletions csv-clock-in-out/employeeMaker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import csv
import random

# List of employee names to add
employee_names = ["Jakub", "Kacper", "Jan", "Antoni", "Michał",
"Szymon", "Filip", "Mateusz", "Paweł", "Adam", "Mateusz"]

# File name for employee storage
employee_file = 'employees.csv'

# Function to add employee names and their shifts to a CSV file
def add_employees(names, filename):
with open(filename, mode='w', newline='', encoding='utf-8') as file:
for name in names:
# Randomly assign a shift to each employee
shift = random.choice(["(6-14)", "(14-22)","(22-6)"])
# Manually format and write the line to avoid CSV auto-quoting
file.write(f"{name},{shift}\n")

# Adding the employees and their shifts to the file
add_employees(employee_names, employee_file)
11 changes: 11 additions & 0 deletions csv-clock-in-out/employees.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Jakub,(6-14)
Kacper,(6-14)
Jan,(22-6)
Antoni,(22-6)
Michał,(6-14)
Szymon,(14-22)
Filip,(14-22)
Mateusz,(22-6)
Paweł,(22-6)
Adam,(22-6)
Mateusz,(22-6)
Loading

0 comments on commit f612709

Please sign in to comment.