penisularhr / src / modules / cron / update-rest-day-wages.service.ts
update-rest-day-wages.service.ts
Raw
/* eslint-disable no-await-in-loop */
/* eslint-disable @typescript-eslint/naming-convention */
import { Injectable } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import moment from 'moment';

import { EmployeeService } from '../employee/employee.service';
import { MonthlyRecordService } from '../monthly-record/monthly-record.service';

@Injectable()
export class UpdateRestDayWages {
  constructor(
    private monthlyRecordService: MonthlyRecordService,
    private employeeService: EmployeeService,
  ) {}

  isCronRunning = false;

  @Cron('0 45 23 * * *') //Everyday check 1 time
  // eslint-disable-next-line sonarjs/cognitive-complexity
  async updateRestDayWages() {
    if (this.isCronRunning === true) {
      return;
    }

    // Get the current date
    const today = moment.utc();

    // Check if today is the last day of the month
    const isEndOfMonth = today.isSame(today.endOf('month'), 'day');

    if (!isEndOfMonth) {
      return;
    }

    this.isCronRunning = true;

    const employees = await this.employeeService.findManyWithoutPagination({
      isActive: true,
    });

    if (employees.length === 0) {
      this.isCronRunning = false;

      return;
    }

    const currentDate = moment.utc().startOf('month');

    // Get the number of days in the month
    const daysInMonth = currentDate.daysInMonth();

    let sundayCount = 0;

    // Loop through the days of the month and count how many are Sundays (0 in Moment.js)
    for (let day = 0; day < daysInMonth; day++) {
      const date = currentDate.clone().add(day, 'days');

      if (date.isoWeekday() === 7) {
        sundayCount++;
      }
    }

    for (const employee of employees) {
      if (employee.dateResign && moment.utc().toDate() > employee.dateResign) {
        continue;
      }

      let restDayWages = sundayCount * employee.dailyRateAmount;

      // If join month === monthly record month
      if (
        moment.utc(employee.dateJoin).startOf('month').toDate() ===
        currentDate.toDate()
      ) {
        restDayWages = 0;
      }

      // If resign month === monthly record month
      if (
        employee.dateResign &&
        moment.utc(employee.dateResign).startOf('month').toDate() ===
          currentDate.toDate()
      ) {
        restDayWages = 0;
      }

      const employeeMonthlyRecord = await this.monthlyRecordService.findOne({
        employee: { id: employee.id },
        date: currentDate.toDate(),
      });

      if (!employeeMonthlyRecord) {
        continue;
      }

      await this.monthlyRecordService.updateMonthlyRecord(
        employeeMonthlyRecord,
        {
          restDayWages,
        },
      );
    }

    this.isCronRunning = false;
  }
}