jurgendn's picture
[Fix] Return 0 with invalid records, fix wrong time
888971b
raw
history blame
5.85 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.checkin > self.AFTERNOON_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
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')
print(late_checkin_penalty)
print(early_checkout_penalty)
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