jurgendn's picture
[Fix] Wrong afternoon_shift
6ab2910
raw
history blame
5.64 kB
from datetime import datetime
from typing import Dict, List
import pandas as pd
from dateutil.parser import parse
from type_alias import EARLY_MODE, LATE_MODE
class WorkingTime(object):
def __init__(self, date: datetime, checkin: str, checkout: str,
config) -> None:
self.MORNING_IN = parse(config.WORKING_TIME.MORNING_IN)
self.MORNING_OUT = parse(config.WORKING_TIME.MORNING_OUT)
self.AFTERNOON_IN = parse(config.WORKING_TIME.AFTERNOON_IN)
self.AFTERNOON_OUT = parse(config.WORKING_TIME.AFTERNOON_OUT)
self.LATE_TIME: Dict[str, int] = dict(
morning_in=config.LATE.MORNING_IN,
morning_out=config.LATE.MORNING_OUT,
afternoon_in=config.LATE.AFTERNOON_IN,
afternoon_out=config.LATE.AFTERNOON_OUT)
self.ROUND_GAP = config.WORKING_TIME.ROUND_GAP
self.date = datetime.strftime(date, "%d/%m/%Y")
self.error: bool = False
if checkin == 0:
# self.checkin = -1
self.error = True
else:
self.checkin = parse(checkin)
if self.checkin < self.MORNING_IN:
self.checkin = parse("08:00")
if checkout == 0:
# self.checkout = -1
self.error = True
else:
self.checkout = parse(checkout)
if self.checkout > self.AFTERNOON_OUT:
self.checkout = parse("17:00")
def __repr__(self) -> str:
return "{" + ";\n".join(f"{k}={getattr(self, k)}"
for k in self.__dict__) + "}"
def get_late_checkin(self, time: datetime, mode: LATE_MODE) -> int:
is_penalty_count: int = 0
if mode == 'morning_in':
target_time: datetime = self.MORNING_IN
acceptable: int = self.LATE_TIME.get('MORNING_IN', 30)
elif mode == 'afternoon_in':
target_time: datetime = self.AFTERNOON_IN
acceptable: int = self.LATE_TIME.get('AFTERNOON_IN', 30)
if time < target_time:
return 0
late_time = (time - target_time).seconds // 60
if late_time > acceptable:
is_penalty_count = 1
return is_penalty_count * late_time
def get_early_checkout(self, time: datetime, mode: EARLY_MODE) -> int:
is_penalty_count: int = 0
if mode == 'morning_out':
target_time: datetime = self.MORNING_OUT
acceptable: int = self.LATE_TIME.get('MORNING_OUT', 0)
elif mode == 'afternoon_out':
target_time: datetime = self.AFTERNOON_OUT
acceptable: int = self.LATE_TIME.get('AFTERNOON_OUT', 0)
if time > target_time:
return 0
early_time = (target_time - time).seconds // 60
if early_time > acceptable:
is_penalty_count = 1
return is_penalty_count * early_time
def morning_shift(self):
if self.error:
return 0
if self.checkin > self.MORNING_OUT:
return 0
if self.checkout < self.MORNING_IN:
return 0
late_checkin_penalty = self.get_late_checkin(time=self.checkin,
mode='morning_in')
early_checkout_penalty = self.get_early_checkout(time=self.checkout,
mode='morning_out')
return (self.MORNING_OUT - self.MORNING_IN
).seconds // 60 - late_checkin_penalty - early_checkout_penalty
def afternoon_shift(self):
if self.error:
return 0
if self.checkout < self.AFTERNOON_IN:
return 0
if self.checkin > self.AFTERNOON_OUT:
return 0
late_checkin_penalty = self.get_late_checkin(time=self.checkin,
mode='afternoon_in')
early_checkout_penalty = self.get_early_checkout(time=self.checkout,
mode='afternoon_out')
return (self.AFTERNOON_OUT - self.AFTERNOON_IN
).seconds // 60 - late_checkin_penalty - early_checkout_penalty
def working_time(self):
return self.morning_shift() + self.afternoon_shift()
def normalize(self, num: int) -> int:
gap = 15
return round(num / gap) * gap
def to_tuple(self):
if self.error:
return self.date, 0
return self.date, self.normalize(self.working_time())
class Employee(object):
def __init__(self,
id: str,
name: str,
workdate: Dict[str, int] = {}) -> None:
self.id = id
self.name = name
self.workdate = workdate
def __repr__(self) -> str:
return "{" + ";\n".join(f"{k}={getattr(self, k)}"
for k in self.__dict__) + "}"
class WorkingTable(object):
def __init__(self) -> None:
pass
def make_table(self, employees: List[Employee]):
id_list: List[str] = []
name_list: List[str] = []
work_date: List[Dict] = []
for employee in employees:
id_list.append(employee.id)
name_list.append(employee.name)
work_date.append(employee.workdate)
work_df: pd.DataFrame = pd.DataFrame(work_date, dtype=int)
info_df: pd.DataFrame = pd.DataFrame({
'Mã nhân viên': id_list,
'Tên nhân viên': name_list
})
working_table: pd.DataFrame = pd.concat(objs=[info_df, work_df],
axis=1)
return working_table