我正在尝试编写一个应用程序,在登录时注册一天的考勤,并将其存储在MongoDB数据库中。
我可以在登录时添加时间戳或时间,但我在一天中只存储一个登录时间或只存储一次考勤时遇到了问题。此外,在上午10-10:15之间登录时应区分attendance
或之后的late attendance
。
我应该如何存储每天的单次出勤率,以便在月底计算总出勤率和迟到出勤率?
mongoose.connect('mongodb://localhost/MYDB',{ useNewUrlParser: true });
const MYDBSchema = new mongoose.Schema({
firstname: { type: String, default: 'default firstname' },
lastname: { type: String, default: 'default lastname' },
password: {type: String, default: 'pass' },
email: { type: String, default: 'hahaha' },
phone: { type: Number},
dob: { type: Date },
attendance:[{
date:{
type:Date,
default:Date.now,
},
entry:{type:Date}
}]
});
要创建考勤,您需要3个集合。
集合1:班次
轮班文件将具有类似的架构
const MYDBSchema = new mongoose.Schema({
name: { type: String, default: 'Default' },
weekend: { type: Array, default: [] },
time: {type: Array, default: [] },
lateIn: { type: Number, default: 0 },
earlyOut: { type: Number, default: 0},
halfDayHour: { type: Number }, // Half Day
fullDayHour: { type: Number } // Full Day
offset: { type: Number } // Timezone offset
assignedEmployee: { type: Array, default: [] }
});
如上所述,模式LateIn、Early Out将具有分钟格式的数字
集合2:每日报告
每日报告文档将具有类似以下的架构
const MYDBSchema = new mongoose.Schema({
user: { type: mongoose.Types.ObjectId}, // Reference of User
shift: { type: mongoose.Types.ObjectId}, // Reference of User
date: { type: Date }, // Start Of The Day Date . Example your offset -330 then store it as "2021-11-26T18:30:00.000Z"
lateIn: { type: Number, default: 0 }, // Will have total LAte In Seconds
earlyOut: { type: Number, default: 0}, // Will have total Early Out Seconds
overTime: { type: Number } // Will have Overtime
breakTime: { type: Number } // Will have total Break Time
initialInTime: { type: Date }, // Will have First Clock In
finalOutTime: { type: Date } // Will have Final Clock Out
totalWorkHour: { type: Number } // Will have Total Working Hour Seconds
dayStatus: { type: Number } // Will define that day is Holiday or Weekend or Working Day
timeStatus: { type: Number } // Will have initial (absent), work (working), break (on break), end (Clocked Out),
});
集合3:时间表
时间表文档将类似于此
const MYDBSchema = new mongoose.Schema({
user: { type: mongoose.Types.ObjectId}, // Reference of User
dailyReport: { type: mongoose.Types.ObjectId}, // Reference of Daily Report
date: { type: Date }, // Start Of The Day Date . Example your offset -330 then store it as "2021-11-26T18:30:00.000Z"
inTime: { type: Date }, // Will have Clock In / Break In
outTime: { type: Date } // Will have Clock Out / Break Out
duration: { type: Number } // Will have Duration in Seconds difference between inTime and outTime
type: { type: Number } // Break or Work
});
->轮班将如何运作
日常运行CRON创建功能,通过将timeStatus设置为初始为每个用户的日常创建条目
->每日报告如何运作
当任何用户发送打卡请求时。首先需要获取班次,然后从班次中获取时区偏移量。转换该日期并获取每日报告。
->创建类似的功能
getShiftTiming({shiftObject,date})->将返回包含{willStartAt:Date,endAt:Date}的对象
getCurrentTiming({date})->将获取每日报告并将其发送给客户端
addIn({date,type})->将获取DailyReport,然后在TimeSheets集合中创建条目作为inTime,然后根据参数类型将timeStatus更改为WORK/BREAK
addOut({date})->将获取每日报告,然后获取最后一份时间表,然后设置时间
calculateDailyReport({shiftDetail,dailyReportDetail})->将根据时间表集合计算报表。它将根据Daily Report获取所有记录,并汇总持续时间,更新dailyReport的totalWorkingHour,中断并获取第一个时间表的inTime和最后一个时间表的outTime,然后设置dailyReport初始inTime=inTime和最终outTime=outTime。该函数中的另一个函数将被调用,它将(lateIn->getShiftTiming调用该函数,然后获得initialInTime和willStart之间的差值。它将是Late In seconds,overTime->Substract breakTime from totalTime,然后用shiftDetail的fullDayWorkingHour检查它,你将获得overTime seconds,就像反向逻辑可以获得earlyOutTime一样)
通过这种方式,您可以管理Shift。我还在ubsapp.com上成功地管理了Shift,它比这个例子更具动态性。它有额外的功能,允许用户更新和添加插槽和请求(基于GEO定位和IP接入的时钟输入和时钟输出很多其他。)