入离职

This commit is contained in:
Àî×ÚÕñ 2022-07-27 16:54:15 +08:00
parent b993f3251e
commit 9eef1571bd
6 changed files with 411 additions and 11 deletions

View File

@ -8,7 +8,7 @@ from motor.motor_asyncio import AsyncIOMotorDatabase
from utils.dingding import get_redis_alluid, send_dates
from utils.jianli import get_resume
from utils.func import get_every_days, get_every_months
from utils.func import get_every_days, get_every_weeks, get_every_months
import crud, schemas
from datetime import datetime
from core.configuration import *
@ -778,11 +778,132 @@ async def year_trend_form(
res_msg[chk_date]['入职人数'] += 1 * count_num
if chk_stage >= 8:
res_msg[chk_date]['转正人数'] += 1 * count_num
if chk_stage >= 9:
if chk_stage == 9:
res_msg[chk_date]['离职人数'] += 1 * count_num
res_msg[chk_date]['主动离职'] += 1 * count_num
if chk_stage >= 10:
if chk_stage == 10:
res_msg[chk_date]['离职人数'] += 1 * count_num
res_msg[chk_date]['被动离职'] += 1 * count_num
return schemas.Msg(code=200, msg='ok', data=res_msg)
# 年度岗位招聘数据报表
@router.post("/year_job_form")
async def year_job_form(
request: Request,
interview: InterviewDo = Depends(InterviewDo),
ck_db: CKDrive = Depends(get_ck_db),
db: AsyncIOMotorDatabase = Depends(get_database)
) -> schemas.Msg:
""" 岗位招聘数据分析报表 """
await interview.init()
res = interview.year_job_form_sql()
sql = res['sql']
data = await ck_db.execute(sql)
if not data:
return schemas.Msg(code=-9, msg='无数据', data=None)
# 取出job和部门
job_ids = set([j_data['job_id'] for j_data in data.values()])
job_ids = list(job_ids)
job_datas = await crud.jobs.find_job_some(db, job_ids)
job_dict = {job['job_id']: {'name': job['job_name'], 'sector': job['job_sector']} for job in job_datas}
sdate = res['sdate']
edate = res['edate']
chk_type = res['chk_type']
if chk_type == 'day':
months = get_every_days(sdate, edate)
elif chk_type == 'week':
months = get_every_weeks(sdate, edate)
else:
months = get_every_months(sdate, edate)
res_msg = {}
for i in months:
res_msg[str(i)] = {}
for job_id in job_ids:
res_msg[str(i)][job_id] = {
'简历推荐数': 0,
'有效简历数': 0,
'到场面试数': 0,
'面试通过': 0,
'offer发出数': 0,
'入职人数': 0,
'离职人数': 0
}
for chk_data in data.values():
if chk_type == 'month':
chk_date = datetime.strftime(chk_data['date'], '%Y-%m')
else:
chk_date = datetime.strftime(chk_data['date'], '%Y-%m-%d')
if chk_date not in res_msg:
continue
chk_stage = chk_data['interview_stage']
count_num = chk_data['value']
chk_job_id = chk_data['job_id']
if chk_stage >= 1:
res_msg[chk_date][chk_job_id]['简历推荐数'] += 1 * count_num
if chk_stage >= 2:
res_msg[chk_date][chk_job_id]['有效简历数'] += 1 * count_num
if chk_stage >= 3:
res_msg[chk_date][chk_job_id]['到场面试数'] += 1 * count_num
if chk_stage >= 4:
res_msg[chk_date][chk_job_id]['面试通过'] += 1 * count_num
if chk_stage >= 5:
res_msg[chk_date][chk_job_id]['offer发出数'] += 1 * count_num
if chk_stage >= 7:
res_msg[chk_date][chk_job_id]['入职人数'] += 1 * count_num
if chk_stage >= 9:
res_msg[chk_date][chk_job_id]['离职人数'] += 1 * count_num
res_data = {
'res_msg': res_msg,
'job_data': job_dict
}
return schemas.Msg(code=200, msg='ok', data=res_data)
# 年度入离职数据报表
@router.post("/year_in_out")
async def year_in_out(
request: Request,
interview: InterviewDo = Depends(InterviewDo),
ck_db: CKDrive = Depends(get_ck_db)
) -> schemas.Msg:
""" 年度入离职数据报表 """
await interview.init()
res = interview.year_in_out_sql()
sql_in = res['sql_in']
sql_out = res['sql_out']
data_in = await ck_db.execute(sql_in)
data_out = await ck_db.execute(sql_out)
if not data_in and data_out:
return schemas.Msg(code=-9, msg='无数据', data=None)
sdate = res['sdate']
edate = res['edate']
months = get_every_months(sdate, edate)
res_msg = {
'入职': {},
'离职': {}
}
for i in months:
res_msg['入职'][str(i)] = 0
res_msg['离职'][str(i)] = 0
# 入职数据处理
for in_data in data_in.values():
in_date = datetime.strftime(in_data['date'], '%Y-%m')
if in_date not in res_msg['入职']:
continue
value = in_data['value']
res_msg['入职'][in_date] += value
# 离职数据处理
for out_data in data_out.values():
out_date = datetime.strftime(out_data['date'], '%Y-%m')
if out_date not in res_msg['离职']:
continue
value = out_data['value']
res_msg['离职'][out_date] += value
return schemas.Msg(code=200, msg='ok', data=res_msg)

View File

@ -51,8 +51,8 @@ class CRUDJobs(CRUDBase):
# 获取对应job_id的名字,以及部门, 招聘数量
async def find_job_some(self, db: AsyncIOMotorDatabase, job_ids):
return await self.find_many(db, {'job_id': {"$in": job_ids}},
{'_id': 0, 'job_name': 1, 'job_sector': 1, 'job_num': 1, 'job_id': 1,
'principal': 1})
{'_id': 0, 'job_name': 1, 'job_sector': 1, 'job_num': 1, 'job_id': 1,
'principal': 1})
jobs = CRUDJobs('jobs')

View File

@ -609,11 +609,11 @@ class InterviewDo:
sql += f" where"
if start_time:
if whereStr:
sql += f" and date >= '{start_time}'"
sql += f" and toDate(addHours(`event_time`, 0)) >= '{start_time}'"
else:
sql += f" date >= '{start_time}'"
sql += f" toDate(addHours(`event_time`, 0)) >= '{start_time}'"
if end_time:
sql += f" and date <= '{end_time}'"
sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
# 没有日期条件
else:
if whereStr:
@ -704,11 +704,11 @@ class InterviewDo:
sql += f" where"
if start_time:
if whereStr:
sql += f" and date >= '{start_time}'"
sql += f" and toDate(addHours(`event_time`, 0)) >= '{start_time}'"
else:
sql += f" date >= '{start_time}'"
sql += f" toDate(addHours(`event_time`, 0)) >= '{start_time}'"
if end_time:
sql += f" and date <= '{end_time}'"
sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
# 没有日期条件
else:
if whereStr:
@ -723,6 +723,108 @@ class InterviewDo:
'edate': end_time,
}
# 年度招聘数据sql
def year_job_form_sql(self):
whereStr = ''
is_date = 0
if self.where:
for key, value in self.where.items():
if key in ['start_time', 'end_time', 'chk_type']:
is_date = 1
continue
if isinstance(value, str):
whereStr += str(key) + ' = ' + "'" + value + "'" + ' '
continue
whereStr += str(key) + ' = ' + str(value) + ' '
whereStr = whereStr.strip()
# 有日期条件
start_time = self.where.get('start_time', '')
end_time = self.where.get('end_time', '')
chk_type = self.where.get('chk_type', 'day')
if chk_type == 'day':
select_str = f"toDate(addHours(`event_time`, 0))"
if chk_type == 'week':
select_str = f"toStartOfWeek(addHours(`event_time`, 0))"
if chk_type == 'month':
select_str = f"toStartOfMonth(addHours(`event_time`, 0))"
if is_date:
if whereStr:
sql = f"select {select_str} as date,interview_stage, job_id, count() as value from HR.resumes where {whereStr}"
else:
sql = f"select {select_str} as date,interview_stage, job_id, count() as value from HR.resumes"
if start_time or end_time:
sql += f" where"
if start_time:
if whereStr:
sql += f" and toDate(addHours(`event_time`, 0)) >= '{start_time}'"
else:
sql += f" toDate(addHours(`event_time`, 0)) >= '{start_time}'"
if end_time:
sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
# 没有日期条件
else:
if whereStr:
sql = f"select {select_str} as date,interview_stage, job_id, count() as value from HR.resumes where {whereStr}"
else:
sql = f"select {select_str} as date,interview_stage, job_id, count() as value from HR.resumes"
sql += f" group by date, interview_stage, job_id"
print(sql)
return {
'sql': sql,
'sdate': start_time,
'edate': end_time,
'chk_type': chk_type,
}
# 年度入离值数据sql
def year_in_out_sql(self):
whereStr = ''
if self.where:
for key, value in self.where.items():
if key in ['start_time', 'end_time']:
continue
if isinstance(value, str):
whereStr += str(key) + ' = ' + "'" + value + "'" + ' '
continue
whereStr += str(key) + ' = ' + str(value) + ' '
whereStr = whereStr.strip()
# 有日期条件
start_time = self.where.get('start_time', '')
end_time = self.where.get('end_time', '')
select_in_str = f"toStartOfMonth(addHours(`in_time`, 0))"
select_out_str = f"toStartOfMonth(addHours(`out_time`, 0))"
if whereStr:
sql_in = f"select {select_in_str} as date, count() as value from HR.resumes where {whereStr}"
sql_out = f"select {select_out_str} as date, count() as value from HR.resumes where {whereStr}"
else:
sql_in = f"select {select_in_str} as date, count() as value from HR.resumes"
sql_out = f"select {select_out_str} as date, count() as value from HR.resumes"
if start_time or end_time:
sql_in += f" where"
sql_out += f" where"
if start_time:
if whereStr:
sql_in += f" and toDate(addHours(`in_time`, 0)) >= '{start_time}'"
sql_out += f" and toDate(addHours(`out_time`, 0)) >= '{start_time}'"
else:
sql_in += f" toDate(addHours(`in_time`, 0)) >= '{start_time}'"
sql_out += f" toDate(addHours(`out_time`, 0)) >= '{start_time}'"
if end_time:
sql_in += f" and toDate(addHours(`in_time`, 0)) <= '{end_time}'"
sql_out += f" and toDate(addHours(`out_time`, 0)) <= '{end_time}'"
sql_in += f" group by date"
sql_out += f" group by date"
print(sql_in, sql_out)
return {
'sql_in': sql_in,
'sql_out': sql_out,
'sdate': start_time,
'edate': end_time,
}
if __name__ == '__main__':
col = 'max_interview_stage'

View File

@ -1,6 +1,7 @@
import random
import time
import datetime
from math import ceil
import pandas as pd
import smtplib
from email.mime.text import MIMEText
@ -307,5 +308,32 @@ def get_every_months(sdate, edate):
return month_range
# 获取两个日期之间所有的周日日期
def get_every_weeks(sdate, edate):
start_date = datetime.datetime.strptime(sdate, '%Y-%m-%d')
end_date = datetime.datetime.strptime(edate, '%Y-%m-%d')
different_day = end_date - start_date
day_num = different_day.days
weeks = int(ceil(day_num / 7))
week_days = []
# 当前周的周末的日期
start_day = get_current_week(start_date)
for i in range(weeks + 1):
day = start_day + timedelta(days=i * 7)
true_day = datetime.datetime.strftime(day, '%Y-%m-%d')
week_days.append(true_day)
return week_days
# 获取当前日期的周日日期
def get_current_week(s_date):
sunday = s_date
one_day = datetime.timedelta(days=1)
while sunday.weekday() != 6:
sunday += one_day
return sunday
if __name__ == '__main__':
get_every_months('2022-01-01', '2022-12-31')

View File

@ -0,0 +1,110 @@
路由: /api/v1/forms/year_job_form
参数:
{
"data_in": "string", # 传''
"interview_query": { # 查询条件
"start_time":"2022-07-10", # 查询区间开始时间 格式固定年-月-日字符串
"end_time":"2022-07-27",
"chk_type":"week" # 'day'表示按天, 'week'表示按周, 'month'表示按月 不传值默认按月
},
"find_column": [ # 传[]
"string"
]
}
返回值:
{
"code": 200,
"msg": "ok",
"data": {
"res_msg": { # 解析数据
"2022-07-10": { # 对应条件下的分组日期
"123": { # job_id
"简历推荐数": 1, # 对应job_id对应的分析数据
"有效简历数": 1,
"到场面试数": 1,
"面试通过": 1,
"offer发出数": 1,
"入职人数": 0,
"离职人数": 0
},
"123456": {
"简历推荐数": 15,
"有效简历数": 14,
"到场面试数": 14,
"面试通过": 13,
"offer发出数": 13,
"入职人数": 2,
"离职人数": 1
}
},
"2022-07-17": {
"123": {
"简历推荐数": 0,
"有效简历数": 0,
"到场面试数": 0,
"面试通过": 0,
"offer发出数": 0,
"入职人数": 0,
"离职人数": 0
},
"123456": {
"简历推荐数": 3,
"有效简历数": 3,
"到场面试数": 3,
"面试通过": 3,
"offer发出数": 3,
"入职人数": 2,
"离职人数": 2
}
},
"2022-07-24": {
"123": {
"简历推荐数": 0,
"有效简历数": 0,
"到场面试数": 0,
"面试通过": 0,
"offer发出数": 0,
"入职人数": 0,
"离职人数": 0
},
"123456": {
"简历推荐数": 0,
"有效简历数": 0,
"到场面试数": 0,
"面试通过": 0,
"offer发出数": 0,
"入职人数": 0,
"离职人数": 0
}
},
"2022-07-31": {
"123": {
"简历推荐数": 0,
"有效简历数": 0,
"到场面试数": 0,
"面试通过": 0,
"offer发出数": 0,
"入职人数": 0,
"离职人数": 0
},
"123456": {
"简历推荐数": 0,
"有效简历数": 0,
"到场面试数": 0,
"面试通过": 0,
"offer发出数": 0,
"入职人数": 0,
"离职人数": 0
}
}
},
"job_data": { # job_id对应的名字,所属部门信息
"123": {
"name": "高级游戏测试工程师",
"sector": "研发部"
}
}
}
}

View File

@ -0,0 +1,39 @@
路由: /api/v1/forms/year_in_out
参数:
{
"data_in": "string", # 传''
"interview_query": { # 查询条件
"start_time":"2022-01-01", # 查询区间开始时间 格式固定年-月-日字符串
"end_time":"2022-07-27",
},
"find_column": [ # 传[]
"string"
]
}
返回值:
{
"code": 200,
"msg": "ok",
"data": {
"入职": { # 入职对应数据
"2022-01": 0, # 月份对应人数
"2022-02": 2,
"2022-03": 1,
"2022-04": 1,
"2022-05": 1,
"2022-06": 1,
"2022-07": 0
},
"离职": {
"2022-01": 0,
"2022-02": 0,
"2022-03": 1,
"2022-04": 0,
"2022-05": 1,
"2022-06": 2,
"2022-07": 2
}
}
}