All files / src/domains/hr/attendance/shift/assignment assignment.service.ts

0% Statements 0/19
0% Branches 0/16
0% Functions 0/4
0% Lines 0/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68                                                                                                                                       
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { EmployeeShiftAssignment, Shift } from '../../schemas';
import { AssignShiftDto } from './dto/assignment.dto';
 
@Injectable()
export class ShiftAssignmentService {
  constructor(
    @InjectModel(EmployeeShiftAssignment.name)
    private assignmentModel: Model<EmployeeShiftAssignment>,
    @InjectModel(Shift.name) private shiftModel: Model<Shift>,
  ) {}
 
  async assignShift(tenantId: string, assignDto: AssignShiftDto) {
    // Verify shift exists
    const shift = await this.shiftModel
      .findOne({ _id: assignDto.shiftId, tenantId })
      .exec();
    if (!shift) {
      throw new NotFoundException(`Shift #${assignDto.shiftId} not found`);
    }
 
    // Usually we would end the previous active assignment for this employee
    // by setting effectiveTo = new effectiveFrom, but keeping it simple for now.
 
    const created = new this.assignmentModel({
      ...assignDto,
      tenantId,
      source: assignDto.source || 'Direct',
      assignmentType: assignDto.assignmentType || 'Employee',
    });
 
    return created.save();
  }
 
  async getEmployeeAssignments(tenantId: string, employeeId: string) {
    return this.assignmentModel
      .find({ tenantId, employeeId })
      .sort({ effectiveFrom: -1 })
      .exec();
  }
 
  async getActiveShiftForEmployeeOnDate(
    tenantId: string,
    employeeId: string,
    targetDate: Date,
  ) {
    // Finds the active assignment on the given date
    const assignment = await this.assignmentModel
      .findOne({
        tenantId,
        employeeId,
        effectiveFrom: { $lte: targetDate },
        $or: [{ effectiveTo: null }, { effectiveTo: { $gte: targetDate } }],
      })
      .sort({ effectiveFrom: -1 })
      .exec();
 
    if (assignment) {
      return this.shiftModel
        .findOne({ _id: assignment.shiftId, tenantId })
        .exec();
    }
    return null;
  }
}