Browse Source

假勤日统计

master
巴林闲侠 2 years ago
parent
commit
84fc979043
  1. 24
      api/app/lib/controllers/member/index.js
  2. 196
      api/app/lib/schedule/attendance.js

24
api/app/lib/controllers/member/index.js

@ -336,9 +336,19 @@ async function overTimeStatistics (ctx) {
GROUP BY overtime.pep_user_id
`).toPromise()
const statisticDayRes = await clickHouse.hr.query(`
SELECT overtime_day.day, sum(overtime_day.duration) AS duration
FROM overtime_day
INNER JOIN overtime
ON overtime.id = overtime_day.overtime_id
AND overtime.pep_user_id = ${pepUserId}
GROUP BY overtime_day.day
`).toPromise()
let returnD = {
...(statisticRes.length ? statisticRes[0] : {}),
data: dataRes
data: dataRes,
dayStatisticData: statisticDayRes
}
ctx.status = 200;
ctx.body = returnD
@ -396,9 +406,19 @@ async function vacateStatistics (ctx) {
GROUP BY type
`).toPromise()
const statisticDayRes = await clickHouse.hr.query(`
SELECT vacate_day.day, sum(vacate_day.duration) AS duration
FROM vacate_day
INNER JOIN vacate
ON vacate.id = vacate_day.vacate_id
AND vacate.pep_user_id = ${pepUserId}
GROUP BY vacate_day.day
`).toPromise()
let returnD = {
statistic: statisticRes,
data: dataRes
data: dataRes,
dayStatisticData: statisticDayRes
}
ctx.status = 200;
ctx.body = returnD

196
api/app/lib/schedule/attendance.js

@ -232,20 +232,104 @@ module.exports = function (app, opts) {
let needData = JSON.parse(JSON.stringify(vacateNeedData))
getData(a, needData)
const { begainTime, endTime, type, hrAffirmType, duration, hrAffirmDuration, reason } = needData
if (begainTime.value && endTime.value && type.value) {
if (
begainTime.value && endTime.value && type.value
&& (duration.value || hrAffirmDuration.value)
) {
let durationSec = 0
if (hrAffirmDuration.value) {
durationSec = parseFloat(hrAffirmDuration.value) * 3600
} else if (duration.value) {
durationSec = parseFloat(duration.value) * 3600
} else {
durationSec = moment(endTime.value).diff(moment(begainTime.value), 'second')
}
if (typeof durationSec != 'number' || isNaN(durationSec) || durationSec <= 0) {
if (
typeof durationSec != 'number'
|| isNaN(durationSec)
|| durationSec <= 0
) {
console.warn('请假时长计算结果错误', hrAffirmDuration, duration);
invalidCount++
} else {
// 计算每个工作日请了多少假
let begainTime_ = moment(begainTime.value)
let endTime_ = moment(endTime.value)
let curTime = begainTime_.clone()
let packageDay = []
let durationDayAddDay = 0
let forenoonDuration = 3600 * 3.5
let afternoonDuration = 3600 * 4.5
let lunchBreakDuration = 3600 * 1
while (curTime.isBefore(endTime_) && durationDayAddDay < durationSec) {
let curDayStr = curTime.format('YYYY-MM-DD')
const holidayRes = await judgeHoliday(curDayStr)
if (holidayRes && holidayRes.workday) {
// 只有上班的日子才计算
let workdayForenoonStart = moment(curDayStr + ' 08:30:00')
let workdayForenoonEnd = moment(curDayStr + ' 12:00:00')
let workdayAfternoonStart = moment(curDayStr + ' 13:00:00')
let workdayAfternoonEnd = moment(curDayStr + ' 17:30:00')
let calcStartTime = workdayForenoonStart.clone()
if (calcStartTime.isSame(begainTime_, 'day')) {
// 和开始日期是同一天就取开始日期
calcStartTime = curTime.clone()
}
if (calcStartTime.isBefore(workdayForenoonStart)) {
// 在上班开始之前 取上班开始时间
calcStartTime = workdayForenoonStart.clone()
} else if (calcStartTime.isBetween(workdayForenoonEnd, workdayAfternoonStart, null, '()')) {
// 在午休时间内取下午上班时间
calcStartTime = workdayAfternoonStart.clone()
}
let calcEndTime = workdayAfternoonEnd.clone()
if (calcEndTime.isSame(endTime_, 'day')) {
// 和结束日期是同一天就取结束时间
calcEndTime = endTime_.clone()
}
if (calcEndTime.isBefore(workdayForenoonStart)) {
// 在上班开始之前
calcEndTime = null
} else if (calcEndTime.isBetween(workdayForenoonEnd, workdayAfternoonStart, null, '()')) {
// 在午休时间内取上午下班时间
calcEndTime = workdayAfternoonStart.clone()
} else if (calcEndTime.isAfter(workdayAfternoonEnd)) {
// 在下午下班之后 取下午下班时间
calcEndTime = workdayAfternoonEnd.clone()
}
if (calcStartTime && calcEndTime && calcStartTime.isBefore(calcEndTime)) {
let durationDay = calcEndTime.diff(calcStartTime, 'seconds')
if (calcStartTime.isBefore(workdayForenoonEnd) && calcEndTime.isAfter(workdayAfternoonStart)) {
// 跨越了午休时间
durationDay -= lunchBreakDuration
}
durationDayAddDay += durationDay
if (durationDayAddDay > durationSec) {
console.log(`请假每日持续时间之和已超过认定时间:day ${curDayStr} duration ${durationDay}`);
durationDay = durationSec - durationDayAddDay
}
if (durationDay > 0) {
packageDay.push({
day: curDayStr,
duration: durationDay
})
}
}
}
curTime = curTime.add(1, 'day').startOf('day')
}
let typeStorage = ''
if (hrAffirmType.value) {
typeStorage = hrAffirmType.value
@ -253,11 +337,12 @@ module.exports = function (app, opts) {
typeStorage = type.value
}
const existRes = await models.Vacate.findOne({
where: {
pepProcessStoryId: a.historyId
}
})
const existRes =
await models.Vacate.findOne({
where: {
pepProcessStoryId: a.historyId
}
})
let storageD = {
pepUserId: a.pepUserId,
pepProcessStoryId: a.historyId,
@ -268,17 +353,36 @@ module.exports = function (app, opts) {
wfProcessState: a.state,
reason: reason.value
}
let storagedId = null
if (existRes) {
await models.Vacate.update(storageD, {
where: {
id: existRes.id
}
})
// 结束且存在 当前条件下没必要更新
// await models.Vacate.update(storageD, {
// where: {
// id: existRes.id
// }
// })
// storagedId = existRes.id
updateCount++
} else {
await models.Vacate.create(storageD)
let res = await models.Vacate.create(storageD)
storagedId = res.id
insertCount++
}
if (storagedId) {
await models.VacateDay.destroy({
where: {
vacateId: storagedId
}
})
if (packageDay.length) {
await models.VacateDay.bulkCreate(packageDay.map(p => {
return {
...p,
vacateId: storagedId
}
}))
}
}
}
} else {
console.warn('必填 value 缺失:', needData,);
@ -320,6 +424,7 @@ module.exports = function (app, opts) {
let packageDay = []
while (curday.isSameOrBefore(endTimeWithHrAffirm)) {
let duration_ = 0
let curDayStr = curday.format('YYYY-MM-DD')
if (curday.isSame(endTimeWithHrAffirm, 'day')) {
// 是同一天
duration_ = endTimeWithHrAffirm.diff(curday, 'seconds')
@ -334,7 +439,11 @@ module.exports = function (app, opts) {
// 不但 curday 加 后一天也加
duration_ = 24 * 3600
}
const holidayRes = await judgeHoliday(curday.format('YYYY-MM-DD'))
packageDay.push({
day: curDayStr,
duration: duration_
})
const holidayRes = await judgeHoliday(curDayStr)
if (holidayRes) {
if (compensate.value && compensate.value.indexOf('调休') >= 0) {
if (holidayRes.workday) {
@ -369,11 +478,12 @@ module.exports = function (app, opts) {
curday = curday.add(1, 'day').startOf('day')
}
if (packageSuccess) {
const existRes = await models.Overtime.findOne({
where: {
pepProcessStoryId: a.historyId
}
})
const existRes =
await models.Overtime.findOne({
where: {
pepProcessStoryId: a.historyId
}
})
let storageD = {
pepUserId: a.pepUserId,
pepProcessStoryId: a.historyId,
@ -390,17 +500,37 @@ module.exports = function (app, opts) {
compensate: compensate.value,
reason: reason.value
}
let storagedId = null
if (existRes) {
await models.Overtime.update(storageD, {
where: {
id: existRes.id
}
})
// 结束且存在 当前条件下没必要更新
// storagedId = existRes.id
// await models.Overtime.update(storageD, {
// where: {
// id: existRes.id
// }
// })
updateCount++
} else {
await models.Overtime.create(storageD)
let res = await models.Overtime.create(storageD)
storagedId = res.id
insertCount++
}
if (storagedId) {
await models.OvertimeDay.destroy({
where: {
overtimeId: storagedId
}
})
if (packageDay.length) {
await models.OvertimeDay.bulkCreate(packageDay.map(p => {
return {
...p,
overtimeId: storagedId
}
}))
}
}
}
} else {
console.warn(`结束时间在开始时间之前(unbelievable)`, '开始' + begainTime.value, '结束' + endTime.value, '人事确认结束' + endTimeWithHrAffirm.format());
@ -426,14 +556,14 @@ module.exports = function (app, opts) {
console.info(`
假勤数据更新 用时 ${moment().diff(startTime, 'seconds')} s
`)
`)
console.info(`
${attendanceRes.length};
新增${insertCount};
更新数据${updateCount};
非完成状态流程${unCompletedCount};
不明流程${unknowCount}
无效(warning)${invalidCount};
新增${insertCount};
更新数据${updateCount};
非完成状态流程${unCompletedCount};
不明流程${unknowCount}
无效(warning)${invalidCount};
`);
} catch (error) {
app.fs.logger.error(`sechedule: updateAttendance, error: ${error} `);

Loading…
Cancel
Save