Browse Source

fix 实际请假时间少于认定时间的计算方式

master
巴林闲侠 2 years ago
parent
commit
478c2184a6
  1. 143
      api/app/lib/controllers/attendance/index.js
  2. 6
      api/app/lib/routes/attendance/index.js
  3. 11
      api/app/lib/schedule/attendance.js
  4. 20
      api/app/lib/utils/constant.js
  5. 2
      api/app/lib/utils/xlsxDownload.js

143
api/app/lib/controllers/attendance/index.js

@ -1,5 +1,6 @@
'use strict'; 'use strict';
const moment = require('moment') const moment = require('moment')
const fs = require('fs');
async function overtimeStatistic (ctx) { async function overtimeStatistic (ctx) {
try { try {
@ -48,7 +49,7 @@ async function exportOvertimeStatistic (ctx) {
try { try {
const { models } = ctx.fs.dc; const { models } = ctx.fs.dc;
const { clickHouse } = ctx.app.fs const { clickHouse } = ctx.app.fs
const { memberList, packageUserData, overtimeStatisticListDayType } = ctx.app.fs.utils const { memberList, packageUserData, overtimeStatisticListDayType, simpleExcelDown, dayType, overtimeType } = ctx.app.fs.utils
const { const {
keywordTarget, keyword, limit, page, orderBy, orderDirection, keywordTarget, keyword, limit, page, orderBy, orderDirection,
startDate, endDate, startDate, endDate,
@ -70,12 +71,67 @@ async function exportOvertimeStatistic (ctx) {
startDate, endDate, pepUserIds startDate, endDate, pepUserIds
}) })
returnD.forEach(u => { returnD.forEach(d => {
u.overtimeStatistic = sumRes.filter(s => s.pepUserId == u.pepUserId) d.departmrnt = d.departmrnt.map(dep => dep.name).join('、')
d.role = d.role.map(r => r.name).join('、')
let overtimeStatistic = sumRes.filter(s => s.pepUserId == d.pepUserId)
for (let dayTypeKey in dayType) {
for (let overtimeTypeKey in overtimeType) {
let corOverTimeSta = overtimeStatistic.find(o => o.compensate == overtimeTypeKey && o.dayType == dayTypeKey)
if (corOverTimeSta) {
d[overtimeTypeKey + dayTypeKey] = (corOverTimeSta.duration / 3600)
// .toFixed(1)
}
}
}
for (let overtimeTypeKey in overtimeType) {
d['sum' + overtimeTypeKey] = overtimeStatistic.reduce((sum, o) => {
if (o.compensate == overtimeTypeKey) {
sum += o.duration / 3600
}
return sum
}, 0)
}
}) })
const fileName = `人员信息_${moment().format('YYYYMMDDHHmmss')}` + '.csv' let overtimeTypeHeader = []
const filePath = await simpleExcelDown({ data: exportD, header, fileName: fileName }) let sumOvertimeTypeHeader = []
for (let overtimeTypeKey in overtimeType) {
sumOvertimeTypeHeader.push({
title: `合计${overtimeType[overtimeTypeKey]}加班时长(小时)`,
key: 'sum' + overtimeTypeKey,
defaultValue: 0
})
for (let dayTypeKey in dayType) {
overtimeTypeHeader.push({
title: dayType[dayTypeKey] + '-' + overtimeType[overtimeTypeKey],
key: overtimeTypeKey + dayTypeKey,
defaultValue: 0
})
}
}
const header = [{
title: '员工编号',
key: 'userCode',
}, {
title: '姓名',
key: 'userName',
}, {
title: '所属部门',
key: 'departmrnt',
}, {
title: '职位',
key: 'role',
}, {
title: '加班次数(次)',
key: 'overtimeCount',
},]
.concat(overtimeTypeHeader)
.concat(sumOvertimeTypeHeader)
const fileName = `加班统计_${startDate ? moment(startDate).format('YYYY-MM-DD') : ''}-${endDate ? moment(endDate).format('YYYY-MM-DD') : ''}_${moment().format('YYYYMMDDHHmmss')}` + '.csv'
const filePath = await simpleExcelDown({ data: returnD, header, fileName: fileName })
const fileData = fs.readFileSync(filePath); const fileData = fs.readFileSync(filePath);
ctx.status = 200; ctx.status = 200;
@ -135,7 +191,84 @@ async function vacateStatistic (ctx) {
} }
} }
async function exportVacateStatistic (ctx) {
try {
const { models } = ctx.fs.dc;
const { clickHouse } = ctx.app.fs
const { memberList, packageUserData, vacateStatisticListDayType, overtimeStatisticListDayType, simpleExcelDown, dayType, overtimeType } = ctx.app.fs.utils
const {
keywordTarget, keyword, limit, page, orderBy, orderDirection,
startDate, endDate,
} = ctx.query
const vacateTypeRes = await clickHouse.hr.query(`
SELECT type FROM vacate GROUP BY type
`).toPromise()
const userRes = await memberList({
keywordTarget, keyword, limit, page,
orderBy, orderDirection,
vacateDayStatisticStartDate: startDate,
vacateDayStatisticendDate: endDate,
vacateDurationStatistic: true,
vacateCountStatistic: true,
vacateCountStatisticStartDate: startDate,
vacateCountStatisticendDate: endDate,
})
let { packageUser: returnD, pepUserIds } = await packageUserData(userRes)
const sumRes = await vacateStatisticListDayType({
startDate, endDate, pepUserIds
})
returnD.forEach(u => {
u.vacateStatistic = sumRes.filter(s => s.pepUserId == u.pepUserId)
u.vacateDayStatisticDuration = (u.vacateDayStatisticDuration) || 0 / 3600
})
const header = [{
title: '员工编号',
key: 'userCode',
}, {
title: '姓名',
key: 'userName',
}, {
title: '所属部门',
key: 'departmrnt',
}, {
title: '职位',
key: 'role',
}, {
title: '合计请假次数(次)',
key: 'vacateCount',
defaultValue: 0,
}, {
title: '合计请假时长(小时)',
key: 'vacateDayStatisticDuration',
defaultValue: 0,
}]
const fileName = `请假统计_${startDate ? moment(startDate).format('YYYY-MM-DD') : ''}-${endDate ? moment(endDate).format('YYYY-MM-DD') : ''}_${moment().format('YYYYMMDDHHmmss')}` + '.csv'
const filePath = await simpleExcelDown({ data: returnD, header, fileName: fileName })
const fileData = fs.readFileSync(filePath);
ctx.status = 200;
ctx.set('Content-Type', 'application/x-xls');
ctx.set('Content-disposition', 'attachment; filename=' + encodeURI(fileName));
ctx.body = fileData;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
module.exports = { module.exports = {
overtimeStatistic, overtimeStatistic,
exportOvertimeStatistic,
vacateStatistic, vacateStatistic,
exportVacateStatistic,
}; };

6
api/app/lib/routes/attendance/index.js

@ -6,6 +6,12 @@ module.exports = function (app, router, opts) {
app.fs.api.logAttr['GET/attendance/overtime'] = { content: '加班统计', visible: true }; app.fs.api.logAttr['GET/attendance/overtime'] = { content: '加班统计', visible: true };
router.get('/attendance/overtime', attendance.overtimeStatistic); router.get('/attendance/overtime', attendance.overtimeStatistic);
app.fs.api.logAttr['GET/attendance/overtime/export'] = { content: '加班统计导出', visible: true };
router.get('/attendance/overtime/export', attendance.exportOvertimeStatistic);
app.fs.api.logAttr['GET/attendance/vacate'] = { content: '请假统计', visible: true }; app.fs.api.logAttr['GET/attendance/vacate'] = { content: '请假统计', visible: true };
router.get('/attendance/vacate', attendance.vacateStatistic); router.get('/attendance/vacate', attendance.vacateStatistic);
app.fs.api.logAttr['GET/attendance/vacate/export'] = { content: '请假统计导出', visible: true };
router.get('/attendance/vacate/export', attendance.exportVacateStatistic);
}; };

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

@ -330,6 +330,14 @@ module.exports = function (app, opts) {
curTime = curTime.add(1, 'day').startOf('day') curTime = curTime.add(1, 'day').startOf('day')
} }
if (durationDayAddDay < durationSec) {
console.log(`请假每日持续时间之和少于认定时间,补偿之`);
// 每日持续时间比认定时间少
if (packageDay.length) {
packageDay[packageDay.length - 1].duration += durationSec - durationDayAddDay
}
}
let typeStorage = '' let typeStorage = ''
if (hrAffirmType.value) { if (hrAffirmType.value) {
typeStorage = hrAffirmType.value typeStorage = hrAffirmType.value
@ -477,6 +485,9 @@ module.exports = function (app, opts) {
} }
curday = curday.add(1, 'day').startOf('day') curday = curday.add(1, 'day').startOf('day')
} }
if (packageSuccess) { if (packageSuccess) {
const existRes = const existRes =
await models.Overtime.findOne({ await models.Overtime.findOne({

20
api/app/lib/utils/constant.js

@ -0,0 +1,20 @@
'use strict';
module.exports = function (app, opts) {
const dayType = {
dayoff: '普假',
workday: '工作日',
festivals: '法定假',
}
const overtimeType = {
'发放加班补偿': '折算',
'调休': '调休'
}
return {
dayType,
overtimeType,
}
}

2
api/app/lib/utils/xlsxDownload.js

@ -59,7 +59,7 @@ module.exports = function (app, opts) {
indexCell.style = headerStyle indexCell.style = headerStyle
for (let h of header) { for (let h of header) {
const cell = row.addCell(); const cell = row.addCell();
cell.value = data[i][h.key]; cell.value = data[i][h.key] || h.defaultValue || '';
cell.style = style cell.style = style
} }
} }

Loading…
Cancel
Save