Merge objects in JavaScript if conditions are met

55 Views Asked by At

I need to join different objects depending on their conditions.

Context

The theme is to calculate the hours that a user accumulates during a full week, let's call it "tracking".

I have an array where I store the daily history of the hours that a user performs daily represented by 'data_daily'

The following array stores the current weekly information of the day that is being consulted, for example, 2022-10-28 is consulted, so its week is from 2022-10-24 to 2022-10-30, which is represented by 'data_week'

However, there are different cases of important uses to highlight:

--- If a user does not record hours on a certain day, that means there will be no record of his hours, right? It's obvious, but to know the reason why he didn't meet his hours, it is stored in 'time_off_request_query' where the reason why he didn't track is specified and if he has an excuse or not give him a minimum of hours or by default zero

So to better understand this let's see it in an example

The user with ID 1234 did not mark hours on October 30 and when consulting the daily information for that day it does not come to us, but we have to store in 'time_off_request_query' that it was missing due to an authorized permission, and a minimum number of hours will be assigned per agreement

Time Off Request

[{
user_id: 1234,
reason: 'authorized permission',
input_date: 2022-10-31,
departure_date: 2022-10-29,
min_tracked: 4
}]

Then, when consulting the weekly information, we obtain that in the week from 2022-10-24 to 2022-10-30, specifically during the days that he did attend, he did 40 hours of work plus the minimum 4 hours assigned to him by agreement for the day 2022 -10-29 gives a total of 44 hours

Weekly Information

[{
  user_id: 1234,
  weklyConsulting: '2022-10-24 / 2022-10-30',
   tracking Weekly: 44
}]

And when consulting the daily information of 2022-10-29 we obtain the minimum hours that were assigned by agreement

[{
  user_id: 1234,
  date: '2022-10-30',
   trackingDaily: 4
}]

So when joining or merging the objects, a result like the following is expected:

[{
    user_id: 1234,
    date: '2022-10-30',
    trackingDaily: 4,
    weklyConsulting: '2022-10-24 / 2022-10-30',
    tracking Weekly: 44
}]

What are the validations then to take into account

  • If a user did not do hours on the day consulted but has accumulated for the week, the minimum hours added by agreement must be added to the weekly record, as must also be represented in the Daily Information of the day consulted
  • If a user made hours that day consulted but during the week he asked for permission and was assigned minimum hours by agreement, he must bring what he did that day plus his accumulated hours of the week where the total will be taken into account what was get from time_off_request_query

Problem

This is my current code

    export const generateReporteDiarioTesteo = async (req: Request & any, res: Response, next: NextFunction) => {
        try {
            const dayliHoursxTimeWork: DayliHoursxTimeWork[] = [];
            const dataDailyxResume: DayliHoursxResume[] = [];
            const dataWeekxResume: ResumeWeek[] = [];
    
            const hubstaffService = new HubstaffClass();
            const supabaseService = new SupabaseService();
            const configGenerals = new Configs();
    
            let data_daily: DailyActivityJoin[] = [];
            let data_week: DailyDB[] = [];
            let generalConfigs: GeneralConfig[] = [];
            let time_holiday_request: TimeHoliday[] = [];
            let attendance_schedule_request: AttendanceSchedule[] = [];
            let time_off_request_query: TimeOffRequest[] = [];
    
            const promises = [
                hubstaffService.getDailyActivities(req.query.start_date, req.query.end_date, req).then(dataFromHubstaff => {
                    let summedTrackedHubstaff = trackedDataFromApi(dataFromHubstaff);
                    data_daily = summedTrackedHubstaff;
                }),
                supabaseService.getSummaryWeek(req.query.start_date).then(dataFromDB => {
                    let summedTrackedWeekly = trackedData(dataFromDB as any[]);
                    data_week = summedTrackedWeekly;
                }),
                configGenerals.getConfigs().then(dataFromDB => { generalConfigs = dataFromDB as any }),
                configGenerals.get_time_holiday(req.query.start_date).then(dataFromDB => { time_holiday_request = dataFromDB as any }),
                configGenerals.attendance_schedule(req.query.fecha_inicio).then(dataFromDB => { attendance_schedule_request = dataFromDB as any }),
                /** LIST OF USERS WHO DID NOT TRACK THAT DAY REQUESTED */
                configGenerals.time_off_request(req.query.start_date).then(dataFromDB => { time_off_request_query = dataFromDB as any }),
            ];
    
            await Promise.all(promises);
    
            generalConfigs.map(config => {
                dayliHoursxTimeWork.push({
                    dayliHourFullTime: config.fulltime_hours_daily,
                    dayliHourPartTime: config.parttime_hours_daily
                })
});

        /** WEEKLY DATA - REGISTRY OF USERS IN THE WEEK */
        data_week.map(weekData => {
            dataWeekxResume.push({
                user_id: weekData.user_id,
                tracked_weekly: weekData.tracked,
                overall_weekly: weekData.overall,
                keyboard_weekly: weekData.keyboard,
                input_tracked_weekly: weekData.input_tracked,
                mouse_Weekly: weekData.mouse,
                billable_Weekly: weekData.billable,
                manual_Weekly: weekData.manual,
                idle_Weekly: weekData.idle,
                resumed_weekly: weekData.resumed,
                rolTittle: weekData.rol.tittle,
                rolePriority: weekData.rol.priority,
                status: weekData.status,
                username: weekData.username,
                daily_hours: weekData.daily_hours,
                summaryStarts: weekData.summaryStarts,
                time_work: weekData.user.time_work
            });
        });

        /** DAILY DATA */
        data_daily.map(dayli => {
            dataDailyxResume.push({
                user_id: dayli.user_id,
                report_date: dayli.date,
                tracked_daily: dayli.tracked,
                input_tracked_daily: dayli.input_tracked,
                overall_daily: dayli.overall,
                mouse_daily:dayli.mouse,
                billable_daily: dayli.billable,
                manual_daily: dayli.manual,
                idle_daily: dayli.idle,
                resumed_daily: dayli.resumed
            });
        });

        // WEEKLY UNION X DAILY
        const joinWeekDailyTracked = dataDailyxResume.map(dayliData => {
            const weekData = dataWeekxResume.find(item => item.user_id === dayliData.user_id);
            let dataDailyOff = getTimeOff(time_off_request_query, dayliData, weekData, req.query.start_date);
            let dayliWeekOff = getTimeOffWeek(time_off_request_query, dayliData, weekData, req.query.start_date);
            let accWeekOff = getAccTimeOffWeek(time_off_request_query, dayliData, weekData, req.query.start_date)

            return (weekData && dayliData) ? { ...dayliData, ...weekData } : (weekData && !dayliData) ? { ...weekData, ...dataDailyOff } : (!weekData && !dayliData) ? { ...dataDailyOff, dayliWeekOff } : (!dayliData && (weekData && time_off_request_query.length > 0)) ? {...dataDailyOff, ...accWeekOff} : null
        });

        res.json(joinWeekDailyTracked)  } 
catch (error) {
        res.status(500).json({ title: 'API-CIT Error', message: 'Error Interno del Servidor' });
    }
}

Carry out the following functions with the idea of ​​being able to validate each use case that I exposed in the context

export function getTimeOff(time_off_request_query, dayliData, weekData, date) {

    let tracked_off: number = 0;
    let user_id_off: number = 0;
    let username_off: string = '';
    let rol_off: string = '';
    let role_priority_off: string = '';
    let activity_off: string = '';

    // of the time_off_request_query in the week query for each element of the array
    time_off_request_query.forEach(off_time => {
        // if the id is different from the one that brings the daily information
        if (off_time.user_id != dayliData.user_id) {
            // stores the minimum number of hours assigned by agreement + extra information
            tracked_off = off_time.tracked;
            user_id_off = off_time.user_id;
            username_off = off_time.user.name;
            rol_off = off_time.rol.tittle;
            rol_priority_off = off_time.rol.priority;
            activity_off = off_time.activity
        }
    })

    // Return the new object
    let dataDailyOff = {
        user_id: user_id_off,
        report_date: date,
        tracked_daily:tracked_off,
        input_tracked_daily: tracked_off,
        overall_daily: 0,
        mouse_daily: 0,
        billable_daily: 0,
        manual_daily: 0,
        idle_daily: 0,
        resumed_daily: 0,
        username: username_off
    };

    return dataDailyOff;

}

export function getTimeOffWeek(time_off_request_query, dayliData, weekData, date) {

    let tracked_off: number = 0;
    let user_id_off: number = 0;
    let username_off: string = '';
    let rol_off: string = '';
    let role_priority_off: string = '';
    let activity_off: string = '';
    let role_status = true;
    let dayli_hours_off: number = 0;
    let time_work_off: number = 0;

     // of the time_off_request_query in the week query for each element of the array
    time_off_request_query.forEach(off_time => {
         // If the id of the user in daily information is different from the time_off and the id of the weekly information is also different
        if (off_time.user_id != dayliData.user_id && off_time.user_id != weekData.user_id) {
            tracked_off = off_time.tracked;
            user_id_off = off_time.user_id;
            username_off = off_time.user.name;
            rol_off = off_time.rol.tittle;
            rol_priority_off = off_time.rol.priority;
            activity_off = off_time.activity;
            role_status = off_time.user.status
            time_work_off = off_time.user.time_work
        }
    })

    let dayliWeekOff = {
        user_id: user_id_off,
        tracked_weekly:tracked_off,
        overall_weekly:tracked_off,
        keyboard_weekly: 0,
        input_tracked_weekly: 0,
        mouse_weekly: 0,
        billable_Weekly: 0,
        manual_weekly: 0,
        idle_Weekly: 0,
        summarized_weekly: 0,
        rolTitle: rol_off,
        rolePriority: role_priority_off,
        status: role_status,
        username: username_off,
        daily_hours: daily_hours_off,
        summaryStarts: 0,
        time_work: time_work_off
    };

    return dayliWeekOff;

}

export function getAccTimeOffWeek(time_off_request_query, dayliData, weekData, date) {

    let tracked_off: number = 0;
    let user_id_off: number = 0;
    let username_off: string = '';
    let rol_off: string = '';
    let role_priority_off: string = '';
    let activity_off: string = '';
    let role_status = true;
    let dayli_hours_off: number = 0;
    let time_work_off: number = 0;

    // of the time_off_request_query in the week query for each element of the array
    time_off_request_query.forEach(off_time => {
        // If the user id in daily information is equal to the time_off and the id of the weekly information is also equal to the time_off
        if (off_time.user_id != dayliData.user_id && off_time.user_id === weekData.user_id) {
            // fetch the information you found about the time_off of that user_id
            tracked_off = off_time.tracked;
            user_id_off = off_time.user_id;
            username_off = off_time.user.name;
            rol_off = off_time.rol.tittle;
            rol_priority_off = off_time.rol.priority;
            activity_off = off_time.activity;
            role_status = off_time.user.status
            time_work_off = off_time.user.time_work
        }
    })

    let dayliWeekOff = {
        user_id: weekData.user_id,
        // And add it when returning the object
        tracked_weekly: tracked_off + weekData.tracked_weekly,
        overall_weekly: tracked_off + weekData.tracked_weekly,
        keyboard_weekly: weekData.keyboard_weekly,
        input_tracked_weekly: weekData.input_tracked_weekly,
        mouse_Weekly: weekData.mouse_Weekly,
        billable_Weekly: weekData.billable_Weekly,
        manual_Weekly: weekData.manual_Weekly,
        idle_Weekly: weekData.idle_Weekly,
        resumed_weekly: weekData.resumed_weekly,
        rolTittle: weekData.rolTittle,
        rolPrpriority: weekData.rolPriority,
         status: weekData.status,
         username: weekData.username,
         daily_hours: weekData.daily_hours,
         summaryStarts: weekData.summaryStarts,
         time_work: weekData.user.time_work
     };

     return dayliWeekOff;

}

In the code that I present to you, I used functions that were too extensive and even too difficult to read and understand, in addition to different bad practices that I would like to be able to do in another way.

Currently this code is not working for me, the functions that I am trying to implement according to my logic are not correct

How can I do this? Is there a way to do it with Javascript? Or better to look elsewhere?

0

There are 0 best solutions below