All files / libs/assignments/plans/core/src/legacy plan-assignments.service.ts

57.48% Statements 73/127
41.66% Branches 5/12
66.66% Functions 2/3
57.48% Lines 73/127

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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 1281x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x                                                                   1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 10x 10x 10x 10x 10x 10x 10x     10x 10x 10x 10x 10x 2x 2x 10x 10x           10x 10x 6x 6x 10x 10x 10x     10x 10x 10x 10x 2x 2x 10x 10x                     10x 10x     10x 10x 10x 1x  
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
 
import { PlanAssignment, type Company, type Plan, type User } from '@amalia/core/models';
import { type Period } from '@amalia/payout-definition/periods/types';
 
/**
 * Service plan assignment.
 */
@Injectable()
export class PlansAssignmentsService {
  public constructor(
    @InjectRepository(PlanAssignment)
    private readonly planAssignmentRepository: Repository<PlanAssignment>,
  ) {}
 
  /**
   * Find plan assignment by plan id and user id.
   * @param plan
   * @param user
   * @param company
   * @param period
   * @param relations
   */
  public async findPlanAssignmentByPlanAndUser(
    company: Pick<Company, 'id'>,
    plan: Pick<Plan, 'id'>,
    user: User,
    period?: Period,
    relations?: string[],
  ): Promise<PlanAssignment | null> {
    const queryBuilder = this.planAssignmentRepository.createQueryBuilder('planAssignement');

    (relations ?? []).forEach((relation) => {
      queryBuilder.leftJoinAndSelect(`planAssignement.${relation}`, relation);
    });

    const companyId = company.id;
    queryBuilder.where('planAssignement.company = :companyId', { companyId });
    const userId = user.id;
    queryBuilder.andWhere('planAssignement.user = :userId', { userId });
    const planId = plan.id;
    queryBuilder.andWhere('planAssignement.plan = :planId', { planId });

    if (period) {
      // Period StartDate <= EffectiveUntil + Period EndDate >= EffectiveAsOf
      const { startDate, endDate } = period;
      queryBuilder.andWhere('COALESCE(planAssignement.effectiveAsOf, :endDate) <= :endDate', {
        endDate,
      });

      queryBuilder.andWhere('COALESCE(planAssignement.effectiveUntil, :startDate) >= :startDate', {
        startDate,
      });
    }

    return queryBuilder.getOne();
  }
 
  /**
   * Find all assignments attached to a plan and/or a user, optional in the period.
   * @param company
   * @param planIds
   * @param userIds
   * @param period period
   * @param relations query relations to load
   */
  public async findAll(
    companyId: Company['id'],
    planIds: string[] | null,
    userIds: string[] | null,
    period?: Period,
    relations?: string[],
  ): Promise<PlanAssignment[]> {
    if ((!planIds || planIds.length === 0) && !userIds) {
      throw new NotFoundException('No param id');
    }
 
    const queryBuilder = this.planAssignmentRepository.createQueryBuilder('planAssignment');
 
    queryBuilder.where('planAssignment.company = :companyId', { companyId });
    if (relations?.includes('company')) {
      queryBuilder.leftJoinAndSelect('planAssignment.company', 'company');
    }
 
    if (userIds) {
      if (userIds.length === 0) {
        return [];
      }
      queryBuilder.andWhere('planAssignment.user IN (:...userIds)', { userIds });
    }
 
    if (relations?.includes('user')) {
      queryBuilder.leftJoinAndSelect('planAssignment.user', 'user');
    }
 
    if (planIds) {
      if (planIds.length === 0) {
        return [];
      }
      queryBuilder.andWhere('planAssignment.planId IN (:...planIds)', { planIds });
    }
 
    if (relations?.includes('plan')) {
      queryBuilder.leftJoinAndSelect('planAssignment.plan', 'plan');
    }
 
    if (period) {
      // Period StartDate <= EffectiveUntil + Period EndDate >= EffectiveAsOf
      const { endDate, startDate } = period;
      queryBuilder.andWhere('COALESCE(planAssignment.effectiveAsOf, :endDate) <= :endDate', {
        endDate,
      });

      queryBuilder.andWhere('COALESCE(planAssignment.effectiveUntil, :startDate) >= :startDate', {
        startDate,
      });
    }
 
    if (relations?.includes('mainTeam')) {
      queryBuilder.leftJoinAndSelect('planAssignment.mainTeam', 'mainTeam');
    }
 
    return queryBuilder.getMany();
  }
}