Files
django_bartool_ovh/app/odoo_hours/text_conv.py
2024-11-25 19:11:28 +00:00

158 lines
5.2 KiB
Python

import re
from datetime import datetime, timedelta
import holidays
import calendar
import json
def timedelta_to_string(td: timedelta) -> str:
"""Convert a timedelta object to a string in the format HH:MM."""
total_minutes = int(td.total_seconds() / 60)
hours = abs(total_minutes) // 60
minutes = abs(total_minutes) % 60
sign = "-" if td.total_seconds() < 0 else ""
return f"{sign}{hours:02}:{minutes:02}"
def process_input_txt(text: str) -> list:
"""
Process text containing work records and return a sorted list of dictionaries
containing the extracted data.
Args:
text (str): Text containing work records.
Returns:
list[dict]: List of dictionaries containing the fields 'enter', 'exit', and 'duration'.
"""
pattern = re.compile(
r"""
(?P<name>\S+\s\S+)\s+ # Name
(?P<start_date>\d{2}\.\d{2}\.\d{4}\s\d{2}:\d{2}:\d{2})\s+ # Start date
(?P<end_date>\d{2}\.\d{2}\.\d{4}\s\d{2}:\d{2}:\d{2})\s+ # End date
(?P<duration>\d{2}:\d{2}) # Duration
""",
re.VERBOSE,
)
results = []
for line in text.splitlines():
line = line.strip()
if not line:
continue
match = pattern.match(line)
if match:
try:
start_date = datetime.strptime(match.group("start_date"), "%d.%m.%Y %H:%M:%S")
end_date = datetime.strptime(match.group("end_date"), "%d.%m.%Y %H:%M:%S")
duration = timedelta(
hours=int(match.group("duration")[:2]), minutes=int(match.group("duration")[3:])
)
results.append(
{
"enter": start_date,
"exit": end_date,
"duration": duration,
}
)
except ValueError:
# Ignore invalid dates
continue
# Sort results by start date
results.sort(key=lambda x: x["enter"])
return results
def generate_monthly_summary(work_records: list, year: int, month: int) -> list:
# Polska lista dni świątecznych
pl_holidays = holidays.Poland(years=year)
# Liczba dni w miesiącu
_, num_days = calendar.monthrange(year, month)
summary = []
# Oblicz godziny pracy na dzień (8h 15min = 8.25h)
daily_work_hours = timedelta(hours=8, minutes=15)
holiday_work_hours = timedelta(hours=0, minutes=15)
# Suma godzin oczekiwanych i rzeczywistych
total_expected = timedelta(0)
total_actual = timedelta(0)
# Tworzenie wpisów dla każdego dnia
for day in range(1, num_days + 1):
date = datetime(year, month, day)
weekday = date.weekday() # 0 = poniedziałek, ..., 6 = niedziela
is_holiday = date in pl_holidays
should_work = weekday < 5 and not is_holiday # Praca w dni robocze poza świętami
# Aktualizuj oczekiwany czas pracy
if should_work:
total_expected += daily_work_hours
# Znajdź godziny faktyczne dla tego dnia
daily_actual = sum(
(record["duration"]
for record in work_records
if record["enter"].date() == date.date()) , timedelta()
)
total_actual += daily_actual # Dodanie timedelta do sumy
# Dodaj dane do listy podsumowania
summary.append({
"day": date.date(),
"weekday": weekday,
"is_holiday": is_holiday,
"total_expected": timedelta_to_string(total_expected),
"total_actual": timedelta_to_string(total_actual),
"total_diffrance": timedelta_to_string(total_actual - total_expected),
"daily_actual": timedelta_to_string(daily_actual),
"daily_diffrance": timedelta_to_string(daily_actual - (daily_work_hours if should_work else holiday_work_hours if daily_actual >= holiday_work_hours else timedelta(0))),
})
return summary
# text3 = """
# Worked hours
# Attendance Reason
# Marcin Nowak 22.11.2024 07:12:30 22.11.2024 16:05:33 08:53
# Marcin Nowak 21.11.2024 07:25:38 21.11.2024 16:43:19 09:18
# Marcin Nowak 20.11.2024 07:31:46 20.11.2024 15:47:36 08:16
# Marcin Nowak 19.11.2024 07:10:39 19.11.2024 15:54:14 08:44
# Marcin Nowak 18.11.2024 07:13:11 18.11.2024 16:04:15 08:51
# Marcin Nowak 15.11.2024 07:06:31 15.11.2024 15:41:49 08:35
# Marcin Nowak 14.11.2024 06:56:23 14.11.2024 16:11:52 09:15
# Marcin Nowak 13.11.2024 07:12:25 13.11.2024 17:19:58 10:08
# Marcin Nowak 12.11.2024 07:40:57 12.11.2024 16:10:42 08:30
# Marcin Nowak 08.11.2024 07:01:22 08.11.2024 15:48:01 08:47
# Marcin Nowak 07.11.2024 07:07:53 07.11.2024 16:26:30 09:19
# Marcin Nowak 06.11.2024 07:11:46 06.11.2024 16:08:43 08:57
# Marcin Nowak 05.11.2024 07:16:33 05.11.2024 16:10:52 08:54
# Marcin Nowak 04.11.2024 07:28:10 04.11.2024 15:51:19 08:23
# """
# # Przetwórz dane wejściowe
# work_records = process_input_txt(text3)
# date = work_records[-1]["enter"].date()
# monthly_summary = generate_monthly_summary(work_records, date.year, date.month)
# # Przykład wyświetlenia podsumowania
# import pprint
# pprint.pprint(monthly_summary)