Spaces:
Runtime error
Runtime error
File size: 5,638 Bytes
1748405 888971b 1748405 888971b 1748405 888971b 1748405 888971b 1748405 888971b 1748405 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
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
|