2

I am trying to write an application which registers attendance for a day when I login and store it on MongoDB database.

I can add time a timestamp or time when I login, but I'm having trouble storing only one login time for the day or only one attendance. Also the should distinguish attendance when login between 10-10:15am or late attendance after that.

How should I store single attendance for each day so that at end of month I can calculate total attendance and late attendances?

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}


    }]
});
APC
  • 144,005
  • 19
  • 170
  • 281
Balkrushna
  • 41
  • 2
  • 9
  • "How should I store single attendance for each day " - each day is a new document in the collection. Upon login, check today's date and search if a document exists for today. Late attendance: on login, if no document exists for today, create new document, check current time, if it is later than 10:15, late attendance. The Schema should have a bool value: late. When late you set this to true. – SanSolo Dec 23 '18 at 07:28
  • after user login check if any attendance inserted in the same day for this user if no then create function to get attendance type with your logic. – Ahmed Ghoniem Dec 23 '18 at 07:32

1 Answers1

0

To create attendance you need 3 Collections.

Collection 1 : Shift

Shift Document will have Schema like below

        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: [] }
    });

As described above schema LateIn, Early Out will have number in format of Minute

Collection 2 : DailyReport

Daily Report Document will have Schema like below

     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),
});

Collection 3 : TimeSheets

Timesheet Document will look like this

 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
});

-> How shift will work

Everyday Run CRON either create Function that will create entry for everyday of each user by set timeStatus as initial

-> How Daily Report Will work

When ever user sends request for clock in. First need to grab Shift and then get timezone offset from the shift convert that date and fetch daily Report.

-> Create function like this

getShiftTiming({ shiftObject, date }) -> will return Object that contain { willStartAt: Date, endAt: Date }

getCurrentTiming({ date }) -> Will fetch Daily Report to send it to client

addIn ({ date, type }) -> Will fetch DailyReport and then create entry in TimeSheets collection as inTime and then change timeStatus to WORK / BREAK based on param type

addOut ({ date }) -> Will Fetch Daily Report and then fetch last TimeSheet and then set outTime

calculateDailyReport({ shiftDetail, dailyReportDetail }) -> Will calculate report based on TimeSheet Collection. It will fetch all records based on Daily Report and sum up duration and update dailyReport's totalWorkingHour, break and then take first timesheet's inTime and last timesheet's outTime and then set dailyReport's initialInTime = inTime and finalOutTime = outTime. Another function within this function will get called and it will ( lateIn -> getShiftTiming call this function and then get difference between initialInTime and willStart at it will be Late In seconds, overTime -> Substract breakTime from totalTime and then check it with shiftDetail's fullDayWorkingHour you will get overTime Seconds same way reverse logic you can get earlyOutTime )

At this way you can manage Shift. I also successfully managed Shift at ubsapp.com which is heavily dynamic than this example. It has extra feature that will allow user to update and add slots and request ( GEO Location and IP Access based Clock In And Clock Out lot other. )