def set_legal_check(uid): """ Set user's legal checkin & checkout time This function should only run for old employees. :param uid: user id """ session = DB_Session() try: user = session.query(User).filter( User.id == uid, User.is_present == 1 ).one() except sqlalchemy.orm.exc.NoResultFound: print "uid %s not found" % uid return None except sqlalchemy.orm.exc.MultipleResultsFound: print "multiple uid %s found" % uid return None attendances = session.query(Attendance).filter( Attendance.userid == user.id ) for attendance in attendances: if attendance.legal_check_in is not None: print "legal_checkin already set @ %s" % attendance.legal_check_in else: attendance.legal_check_in = datetime.datetime.strptime( "{date} {time}".format(date=attendance.date, time=user.banci), "%Y-%m-%d %H:%M" ) attendance.legal_check_out = attendance.legal_check_in + datetime.timedelta(hours=9) session.commit() session.close()
def update_attendance_status(uid, date): """ Run this method after initialize new database Run set_legal_check first! """ session = DB_Session() try: user = session.query(User).filter( User.id == uid ).one() except sqlalchemy.orm.exc.NoResultFound: print "uid %s not found" % uid return None attendances = session.query(Attendance).filter( Attendance.userid == user.id, Attendance.date == date ).all() for attendance in attendances: the_date = datetime.datetime.strptime(attendance.date, "%Y-%m-%d") if the_date.weekday() in [5, 6]: if attendance.check_in is not None and attendance.check_out is not None: attendance.attendance_status = 10 attendance.is_maintainable = 1 else: attendance.attendance_status = 2 attendance.is_maintainable = 1 else: if attendance.check_in is None or attendance.check_out is None: attendance.attendance_status = 9 attendance.is_maintainable = 2 else: if (attendance.check_in > attendance.legal_check_in) & ((attendance.check_in - attendance.legal_check_in).seconds > 60): if attendance.check_out < attendance.legal_check_out: attendance.attendance_status = 8 attendance.is_maintainable = 2 else: attendance.attendance_status = 6 attendance.is_maintainable = 2 else: if attendance.check_out < attendance.legal_check_out: attendance.attendance_status = 7 attendance.is_maintainable = 2 else: attendance.attendance_status = 2 attendance.is_maintainable = 1 session.commit()
def get_late_overtime_hour(uid, month): """ Get user's late hours in the month :param uid: user id :param month: format 'yyyy-mm' """ session = DB_Session() late_hour_total = 0 overtime_hour_total = 0 user = session.query(User).filter( User.id == uid ).one() attendances = session.query(Attendance).filter( Attendance.userid == user.id, Attendance.date.like("{month}%".format(month=month)) ).order_by(Attendance.date).all() for attendance in attendances: if attendance.attendance_status in [1, 11]: # 考勤状态待定,先不处理 continue if attendance.attendance_status == 2 and datetime.datetime.strptime(attendance.date, "%Y-%m-%d").weekday() in [5, 6]: # 周末,考勤状态正常,不处理 continue if attendance.attendance_status in [2, 3, 4, 6]: # 正常下班情况,计算加班时间 # 正常下班包括:正常、上午请假、下午请假、迟到 overtime_hour_total += (attendance.check_out - attendance.legal_check_out).seconds / 3600 if attendance.attendance_status in [3, 4]: # 请半天假,缺勤4小时 late_hour_total += 4 if attendance.attendance_status in [5, 9]: # 全天假和旷工,缺勤8小时 late_hour_total += 8 if attendance.attendance_status in [6, 8]: # 上班晚,需要计算缺勤时间 late_hour_total += (attendance.check_in - attendance.legal_check_in).seconds / 3600 + 1 if attendance.attendance_status in [7, 8]: # 下班早,需要计算缺勤时间 late_hour_total += (attendance.legal_check_out - attendance.legal_check_out).seconds / 3600 + 1 if attendance.attendance_status in [10]: overtime_hour_total += (attendance.check_out - attendance.check_in).seconds / 3600 # print attendance.date, late_hour_total, overtime_hour_total session.close() return late_hour_total, overtime_hour_total
def get_late_overtime_hour(uid, month): """ Get user's late hours in the month :param uid: user id :param month: format 'yyyy-mm' """ session = DB_Session() late_hour_total = 0 overtime_hour_total = 0 user = session.query(User).filter( User.id == uid ).one() attendances = session.query(Attendance).filter( Attendance.userid == user.id, Attendance.date.like("{month}%".format(month=month)) ).order_by(Attendance.date).all() for attendance in attendances: # 单日缺勤最多8h,增加late_hour变量进行处理 late_hour = 0 # 午休时间 lunch_start = datetime.datetime.strptime("%s 12:00" % attendance.date, "%Y-%m-%d %H:%M") lunch_end = datetime.datetime.strptime("%s 13:00" % attendance.date, "%Y-%m-%d %H:%M") if attendance.attendance_status in [1, 11]: # 考勤状态待定,先不处理 continue if attendance.attendance_status == 2 and datetime.datetime.strptime(attendance.date, "%Y-%m-%d").weekday() in [5, 6]: # 周末,考勤状态正常,不处理 continue if attendance.attendance_status == 13: # 法定节假日 ,考勤状态正常,不处理 continue if attendance.attendance_status in [2, 3, 4, 6]: # 正常下班情况,计算加班时间 # 正常下班包括:正常、上午请假、下午请假、迟到 overtime_hour_total += (attendance.check_out - attendance.legal_check_out).seconds / 3600 if attendance.attendance_status in [3, 4]: # 请半天假,缺勤4小时 late_hour += 4 if attendance.attendance_status in [5, 9]: # 全天假和旷工,缺勤8小时 late_hour += 8 if attendance.attendance_status in [6, 8]: # 上班晚,需要计算缺勤时间 late_hour += (attendance.check_in - attendance.legal_check_in).seconds / 3600 + 1 if (attendance.legal_check_out - attendance.legal_check_in).seconds / 3600 != 9: # 如果用户本身是半天假的状态,需要额外加上请假的4h late_hour += 4 elif attendance.check_in > lunch_end: # 用户正常班,但是上班打卡晚于午休结束 # 这时应该去掉1h的午休时间 late_hour -= 1 if attendance.attendance_status in [7, 8]: # 下班早,需要计算缺勤时间 late_hour += (attendance.legal_check_out - attendance.check_out).seconds / 3600 + 1 if (attendance.legal_check_out - attendance.legal_check_in).seconds / 3600 != 9: # 如果用户本身是半天假的状态,需要额外加上请假的4h late_hour += 4 elif attendance.check_out < lunch_start: # 用户正常班,下班卡早于午休结束时间 # 这时应该去掉1h的午休时间 late_hour -= 1 if attendance.attendance_status in [10]: overtime_hour_total += (attendance.check_out - attendance.check_in).seconds / 3600 # 如最上所述,单日缺勤最多8h late_hour_total += late_hour if late_hour <= 8 else 8 # print attendance.date, late_hour_total, overtime_hour_total session.close() return late_hour_total, overtime_hour_total
def set_attendance_status_daily(date=""): """ A function that runs once a day, in order to set user's attendance attendance If user has checked out, set_attendance_status_on_check_out should be called. So this function should deal with illegal attendance, such as no_check_out, no_attendance_today, etc. """ if not date: date = datetime.datetime.now().strftime("%Y-%m-%d") the_date = datetime.datetime.strptime(date, "%Y-%m-%d") default_check_time = datetime.datetime.strptime("{date}".format(date=date), "%Y-%m-%d") session = DB_Session() users = session.query(User).filter( User.is_present == 1, User.is_admin == 0 ).order_by(User.id).all() for user in users: try: # 用户当天有打卡记录,说明来打过上班卡 attendance = session.query(Attendance).filter( Attendance.userid == user.id, Attendance.date == date ).one() if attendance.attendance_status == 1: # 状态为待定,说明还没打下班卡 attendance.check_out = default_check_time attendance.is_maintainable = 2 if the_date.weekday() in [5, 6]: # 周末加班忘打下班卡…… # 只能算作没加班了…… # ╮(╯▽╰)╭ attendance.attendance_status = 2 else: attendance.attendance_status = 9 else: # 用户的状态已经计算过了,忽略 pass except sqlalchemy.orm.exc.NoResultFound: # 没有找到用户当天的打卡记录 # 需要强势插入一条记录! legal_check_in = datetime.datetime.strptime( "{date} {time}".format(date=date, time=user.banci), "%Y-%m-%d %H:%M" ) legal_check_out = legal_check_in + datetime.timedelta(hours=9) attendance = Attendance( userid=user.id, legal_check_in=legal_check_in, legal_check_out=legal_check_out, date=date, check_in=default_check_time, check_out=default_check_time, updatetime=datetime.datetime.now() ) if the_date.weekday() in [5, 6]: # 周末未打卡,正常 attendance.is_maintainable = 1 attendance.attendance_status = 2 else: # 工作日未打卡,得多大心啊... attendance.is_maintainable = 2 attendance.attendance_status = 9 session.add(attendance) except sqlalchemy.orm.exc.MultipleResultsFound: # 找到当天有多条打卡记录 # todo pass session.commit() session.close()