def cron_weekly_report_hrbp(): """每周的周一上午10:30发送上周的考勤周报给hrbp""" s = Schedule() weekday = s.get_weekday(datetime.date.today().strftime('%Y-%m-%d')) if int(weekday) == 0: weekly = WeeklyReportHrbp() weekly.handle(deptname='pro')
def handle(self, *args, **options): logger.info('init attendance info from dd') default_etime = "%s 23:59:59" % Schedule.get_yesterday().strftime( '%Y-%m-%d') default_stime = "%s 00:00:01" % Schedule.get_yesterday().strftime( '%Y-%m-%d') stime = options.get('stime', default_stime) etime = options.get('etime', default_etime) userid_attid_map = { userobj.userid: userobj.attendence_id for userobj in User.objects.filter(is_delete=False).exclude( workplace__in=['北京', '合肥']) } userid_list = userid_attid_map.keys() for userids in l_yield(userid_list, 50): Att = AttendanceFromDD(stime=stime, etime=etime, userid_list=userids) for userid, mult_records in Att.attendanceinfo().iteritems(): for day, record_info in mult_records.iteritems(): clockin, clockout, worktime = record_info ser = AttendanceRecordSerializer( data={ 'attendence_id': userid_attid_map[userid], 'record_date': day, 'clockin_time': clockin, 'clockout_time': clockout, 'worktime': worktime }) if ser.is_valid(): # print ser.data ser.save() else: logger.warn('%s', ser.errors) logger.info('write to mysql ok ')
def approval_query(self, stime, etime, userid): """自定义审批记录查询,注意此处返回是字典,key为日期""" max_query_day = DEFAULT_ATTENDENCE_RULE.get('MAX_QUERY_DAYS') s = Schedule() ret = {} if not stime or not etime or not userid: return ret days = [day for day in Schedule.iter_diffdays(stime, etime)] if len(days) > max_query_day: return ret try: approval_objs = self.filter(originator_userid=userid, status="COMPLETED", result='agree') for day in days: tmp = [] for approval_obj in approval_objs: stime = approval_obj.start_time.split()[0] etime = approval_obj.end_time.split()[0] if s.check_time_in_range(day, stime, etime): tmp.append(approval_obj) ret[day] = tmp except ObjectDoesNotExist: pass return ret
def default_params(self): s = Schedule() time_now = datetime.date.today().strftime('%Y-%m-%d') default_stime, default_etime = s.get_lastweek(time_now) stime = self.request.GET.get('stime', default_stime) etime = self.request.GET.get('etime', default_etime) stime = stime if stime != '' else default_stime etime = etime if etime != '' else default_etime deptId = self.request.GET.get('deptId', None) return stime, etime, deptId
def handle(self, *args, **options): s = Schedule() time_now = datetime.date.today().strftime('%Y-%m-%d') default_stime, default_etime = s.get_lastweek(time_now) stime = options.get('stime', default_stime) etime = options.get('etime', default_etime) logger.info('ready go') reporter = Reporter() reporter.get_data(stime, etime) logger.info('start send base_weekly_report') # 发送考勤周报给HR reporter.base_weekly_report_to_hr()
def handle(self, *args, **options): logger.info('init attendance info') default_etime = "%s 04:39:59" % datetime.date.today().strftime( '%Y-%m-%d') default_stime = "%s 04:40:00" % Schedule.get_yesterday().strftime( '%Y-%m-%d') stime = options.get('stime', default_stime) etime = options.get('etime', default_etime) Att = Attendance(stime=stime, etime=etime) for jobnumber, mult_records in Att.attendanceinfo().iteritems(): for day, record_info in mult_records.iteritems(): clockin, clockout, worktime = record_info ser = AttendanceRecordSerializer( data={ 'attendence_id': jobnumber, 'record_date': day, 'clockin_time': clockin, 'clockout_time': clockout, 'worktime': worktime }) if ser.is_valid(): ser.save() else: logger.warn('%s', ser.errors) logger.info('write to mysql ok ')
def attendence_query(self, stime, etime, jobnumber): """自定义考勤查询,由于原始记录不存在未打卡的考勤,在此处补上(蛋疼,需要优化""" max_query_day = DEFAULT_ATTENDENCE_RULE.get('MAX_QUERY_DAYS') ret = [] if not stime or not etime or not jobnumber: return ret days = [day for day in Schedule.iter_diffdays(stime, etime)] if len(days) > max_query_day: return ret try: attendence_id = User.objects.get(jobnumber=jobnumber).attendence_id ret = [ recordobj for recordobj in self.filter(record_date__in=days, attendence_id=attendence_id) ] if len(ret) != len(days): result_range = {record.record_date for record in ret} for diff in set(days) - result_range: diffobj = AttendenceRecord(attendence_id=attendence_id, record_date=diff, clockin_time='', clockout_time='', worktime='') ret.append(diffobj) ret.sort(key=sort_key) except ObjectDoesNotExist: pass return ret
def record_query(self, userid, record_dates=None): """查询指定用户 指定日期范围内的请休假记录,返回{day : info,}""" s = Schedule() ret = {} try: approval_objs = self.filter(originator_userid=userid, status="COMPLETED", result='agree') for day in record_dates: tmp = [] for approval_obj in approval_objs: stime = approval_obj.start_time.split()[0] etime = approval_obj.end_time.split()[0] if s.check_time_in_range(day, stime, etime): tmp.append(approval_obj) ret[day] = tmp except ObjectDoesNotExist: pass return ret
def person_stats(self, jobnumber, month): """个人考勤统计""" ret = {} s = Schedule() now_year = datetime.date.today().strftime("%Y") record_dates = [d for d in s.iter_mothdays(int(now_year), int(month))] # 准备前置数据 userobj = User.objects.get(jobnumber=jobnumber) attendence_records = AttendenceRecord.objects.record_query(attendence_id=userobj.attendence_id, record_dates=record_dates) approval_records = ApprovalRecord.objects.record_query(userid=userobj.userid, record_dates=record_dates) holiday_info = Holiday.objects.holiday_info(record_dates=record_dates) # 初始化 unclockin_num = unclockout_num = worktime_lt_num = late_num = early_num = 0 # 计算 for attendence_record in attendence_records: record_date = attendence_record.record_date # 不统计节假日/请休假情况 if not holiday_info.get(record_date, None) and len(approval_records.get(record_date, [])) == 0: if not attendence_record.clockin_time: unclockin_num += 1 if not attendence_record.clockout_time: unclockout_num += 1 if attendence_record.clockin_time_warning: late_num += 1 if attendence_record.clockout_time_warning: early_num += 1 if attendence_record.worktime_warning: worktime_lt_num += 1 # 组装 ret.update( { 'name': userobj.name, 'jobnumber': userobj.jobnumber, 'deptname': Department.objects.query_mult_department(department_id=userobj.department_id).name, 'month': '-'.join([now_year, month]), 'unclockin_num': unclockin_num, 'unclockout_num': unclockout_num, 'worktime_lt_num': worktime_lt_num, 'late_num': late_num, 'early_num': early_num } ) return ret
def handle(self, *args, **options): s = Schedule() time_now = datetime.date.today().strftime('%Y-%m-%d') default_stime, default_etime = s.get_lastweek(time_now) stime = options.get('stime', default_stime) etime = options.get('etime', default_etime) logger.info('ready go') reporter = Reporter() reporter.get_data_2(stime, etime) # args 或者 kargs 指定部门,则发送指定部门的考勤 arg = options.get('deptname', None) if arg != 'pro': deptname = arg logger.info('start send weekly_reprot_to_hrbpto %s', deptname) reporter.base_report_to(deptname) sys.exit(0) logger.info('start send weekly_reprot_to_hrbp') # 发送各部门考勤周报execl给hrbps reporter.weekly_reprot_to_hrbp() # 发送个人周平均出勤小于10的周报execl给hr reporter.base_reprot_to_boss_2_execl()
def handle(self, *args, **options): s = Schedule() time_now = datetime.date.today().strftime('%Y-%m-%d') default_stime, default_etime = s.get_lastweek(time_now) stime = options.get('stime', default_stime) etime = options.get('etime', default_etime) logger.info('ready go') reporter = Reporter() reporter.get_data(stime, etime) # args 或者 kargs 指定部门,则发送指定部门的考勤 arg = options.get('deptname', None) if arg != 'pro': deptname = arg logger.info('start send base_weekly_report to %s', deptname) reporter.base_report_to(deptname) sys.exit(0) logger.info('start send base_weekly_report') # 发送考勤周报给各部门leaders reporter.base_dept_report_to_leaders() # 发送部门平均出勤时间周报给boss reporter.base_reprot_to_boss()
def clean(self): max_query_day = DEFAULT_ATTENDENCE_RULE.get('MAX_QUERY_DAYS') stime = self.cleaned_data['stime'] etime = self.cleaned_data['etime'] if stime and etime: days = [day for day in Schedule.iter_diffdays(stime, etime)] if len(days) > max_query_day: raise forms.ValidationError('最大查询记录需要小于%s天' % max_query_day) else: return self.cleaned_data if not stime and not etime: return self.cleaned_data raise forms.ValidationError('无效的起止日期')
def get_queryset(self): ret = [] stime = self.request.GET.get('stime', None) etime = self.request.GET.get('etime', None) jobnumber = self.request.GET.dict().get('jobnumber', None) try: days = [day for day in Schedule.iter_diffdays(stime, etime)] userid = User.objects.get(jobnumber=jobnumber).userid leave = LeaveInfoFromMysql() for day in days: ret += leave.query_leave_info(userid, day) except Exception: pass return ret
def handle(self, *args, **options): s = Schedule() year = options.get('year') for day in s.iter_yeardays(year): weekday = s.get_weekday(day) weekday_hunman = DEFAULT_WEEKDAY.get(weekday) ret = s.get_holiday(day) is_holiday = ret['holiday'] if ret else False holiday_info = ret['name'] if ret else None try: instance = Holiday.objects.get(day=day) except Holiday.DoesNotExist: instance = None ser = HolidaySerializer(data={ 'day': day, 'weekday': weekday_hunman, 'is_holiday': is_holiday, 'holiday_info': holiday_info }, instance=instance) if ser.is_valid(): ser.save() else: logger.warn('%s', ser.errors)
def default_record_dates(self): """默认的查询日期范围""" s = Schedule() time_now = datetime.date.today().strftime('%Y-%m-%d') default_stime, default_etime = s.get_lastweek(time_now) return [day for day in Schedule.iter_diffdays(default_stime, default_etime)]
def person_approval_stats(self, jobnumber, month): """个人请休假信息统计""" ret = {} s = Schedule() now_year = datetime.date.today().strftime("%Y") record_dates = [d for d in s.iter_mothdays(int(now_year), int(month))] # 准备前置数据 userobj = User.objects.get(jobnumber=jobnumber) attendence_records = AttendenceRecord.objects.record_query(attendence_id=userobj.attendence_id, record_dates=record_dates) approval_records = ApprovalRecord.objects.record_query(userid=userobj.userid, record_dates=record_dates) holiday_info = Holiday.objects.holiday_info(record_dates=record_dates) # 初始化 unclock_day = winter_leave = sick_leave = person_leave = fullpay_sick_leave = halfpay_sick_leave = marriage_leave = maternity_leave \ = siling_leave = dead_leave = baby_leave = 0 # stats for attendence_record in attendence_records: record_date = attendence_record.record_date # 不统计节假日/请休假情况 if not holiday_info.get(record_date, None) and len(approval_records.get(record_date, [])) == 0: if not attendence_record.clockin_time or not attendence_record.clockout_time: unclock_day += 1 # 计算需要去重 has_sum_list = [] for day, approval_objs in approval_records.iteritems(): if len(approval_objs) > 0: for approval_obj in approval_objs: if approval_obj.instance_id not in has_sum_list: if approval_obj.approval_type == u'请假': if approval_obj.aproval_desc in [u'年假']: winter_leave += s.count_diff_day(approval_obj.start_time, approval_obj.end_time, int(month)) if approval_obj.aproval_desc in [u'司龄假']: siling_leave += s.count_diff_day(approval_obj.start_time, approval_obj.end_time, int(month)) if approval_obj.aproval_desc in [u'病假']: sick_leave += s.count_diff_day(approval_obj.start_time, approval_obj.end_time, int(month)) if approval_obj.aproval_desc in [u'事假']: person_leave += s.count_diff_day(approval_obj.start_time, approval_obj.end_time, int(month)) if approval_obj.aproval_desc in [u'全薪病假']: fullpay_sick_leave += s.count_diff_day(approval_obj.start_time, approval_obj.end_time, int(month)) if approval_obj.aproval_desc in [u'半薪病假/事假']: halfpay_sick_leave += s.count_diff_day(approval_obj.start_time, approval_obj.end_time, int(month)) if approval_obj.aproval_desc in [u'婚假']: marriage_leave += s.count_diff_day(approval_obj.start_time, approval_obj.end_time, int(month)) if approval_obj.aproval_desc in [u'丧假']: dead_leave += s.count_diff_day(approval_obj.start_time, approval_obj.end_time, int(month)) if approval_obj.aproval_desc in [u'产检假或陪产假']: maternity_leave += s.count_diff_day(approval_obj.start_time, approval_obj.end_time, int(month)) if approval_obj.aproval_desc in [u'产假']: baby_leave += s.count_diff_day(approval_obj.start_time, approval_obj.end_time, int(month)) has_sum_list.append(approval_obj.instance_id) # 组装 ret.update( { 'name': userobj.name, 'jobnumber': userobj.jobnumber, 'deptname': Department.objects.query_mult_department(department_id=userobj.department_id).name, 'month': '-'.join([now_year, month]), 'unclock_day': unclock_day, 'winter_leave': winter_leave, 'sick_leave': sick_leave, 'person_leave': person_leave, 'fullpay_sick_leave': fullpay_sick_leave, 'halfpay_sick_leave': halfpay_sick_leave, 'marriage_leave': marriage_leave, 'maternity_leave': maternity_leave, 'siling_leave': siling_leave, 'dead_leave': dead_leave, 'baby_leave': baby_leave } ) return ret
def holiday_query(self, stime, etime): days = [day for day in Schedule.iter_diffdays(stime, etime)] return self.filter(day__in=days)
def get(self, request): records = None query_form = QueryFrom(request.GET) if query_form.is_valid(): jobnumber = query_form.cleaned_data['jobnumber'] stime = query_form.cleaned_data['stime'] etime = query_form.cleaned_data['etime'] record_dates = self.default_record_dates() if not stime and not etime else [day for day in Schedule.iter_diffdays(stime, etime)] records = self.person_query(jobnumber=jobnumber, record_dates=record_dates) holidayobjs = {obj.day: obj for obj in Holiday.objects.filter(day__in=record_dates)} execfilename = '-'.join([record_dates[0], record_dates[-1], jobnumber]) return render(request, 'person_query_new.html', locals()) else: errors = query_form.errors return render(request, 'person_query_new.html', locals())
def handle(self, *args, **options): ret = [] s = Schedule() yesterday = Schedule.get_yesterday().strftime('%Y-%m-%d') # 判定昨天是否为工作日 if Holiday.objects.get(day=yesterday).is_holiday: logger.info('%s is holiday', yesterday) return org = OrgFromMysql() org.init_data() leave = LeaveInfoFromMysql() leave.init_data() att = AttendenceFromMysql(stime=yesterday, etime=yesterday) att.init_data() sender = TigerSmtp() # 组装邮件内容 subject = u'%s 未打卡通知' % yesterday default_rec = [''] cc = [''] for userobj in org.get_user(): info = {} # 忽略白名单的考勤通知 if userobj.jobnumber in DEFAULT_WHITE_LIST: continue # 有请休假记录的忽略; if len(leave.get_leave_info(userid=userobj.userid, date=yesterday)) == 0: department_id = sorted(userobj.department_id.split(','))[0] departname = org.dept_id_name_map.get(department_id) info.setdefault('departname', departname) info.setdefault('jobnumber', userobj.jobnumber) info.setdefault('name', userobj.name) info.setdefault('date', yesterday) record = att.attendence_info.get(userobj.attendence_id, []) message = None if len(record) == 0: message = u'当天未有打卡记录' else: if record[0].clockin_time is None or s.check_clockin( record[0].clockin_time): message = u'签到未打卡' if record[0].clockout_time is None: message = u'签退未打卡' # 检测到未打卡记录才发送 if message is not None: info.setdefault('message', message) if userobj.email: rec = [userobj.email] try: msg = sender.create_notify_msg( rec, cc, subject, info) sender.commit(msg, rec) logger.info('send notify to %s ok', rec) info.setdefault('result', u'success') except smtplib.SMTPException as why: logger.info('send notify to %s fail', rec) logger.error(why) info.setdefault('result', why) else: logger.info('%s email addr is None ', userobj.name) info.setdefault('result', u'email is Null') # 发送情况写入数据库 obj = UnclockReport.objects.create( day=yesterday, jobnumber=userobj.jobnumber, unclock_info=message, result=info['result']) obj.save() ret.append(info) # 发送汇总邮件 并写入数据库 result_subject = u'%s 未打卡汇总报告' % yesterday result_rec = [''] try: result_msg = sender.create_notify_result_msg( result_rec, cc, result_subject, ret) sender.commit(result_msg, result_rec + cc) except smtplib.SMTPException as why: logger.info('send notify result to %s fail', result_rec) logger.error(why)