penisularhr / src / modules / incentive / incentive-settings.service.ts
incentive-settings.service.ts
Raw
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { type FindOptionsWhere, Repository } from 'typeorm';

import { type PageDto } from '../../common/dto/page.dto';
import { IncentiveName, OperateType } from '../../constants';
import { AuditLogService } from '../audit-log/audit-log.service';
import { type UserEntity } from '../user/user.entity';
import { type CreateIncentiveSettingDto } from './dtos/create-incentive-settings.dto';
import { type IncentiveSettingPageOptionsDto } from './dtos/get-incentive-settings-page.dto';
import { type IncentiveSettingDto } from './dtos/incentive-settings.dto';
import { type UpdateIncentiveSettingDto } from './dtos/update-incentive-settings.dto';
import { IncentiveSettingEntity } from './incentive-settings.entity';

@Injectable()
export class IncentiveSettingService {
  constructor(
    @InjectRepository(IncentiveSettingEntity)
    private incentiveSettingReposiory: Repository<IncentiveSettingEntity>,
    private auditLogService: AuditLogService,
  ) {}

  async findOne(
    findData: FindOptionsWhere<IncentiveSettingEntity>,
  ): Promise<IncentiveSettingEntity | null> {
    const queryBuilder =
      this.incentiveSettingReposiory.createQueryBuilder('incentiveSetting');

    queryBuilder.where(findData);

    if (findData.name === IncentiveName.LONG_SERVICE) {
      queryBuilder.orderBy('incentiveSetting.threshold', 'ASC');
    }

    return queryBuilder.getOne();
  }

  async findHighestLongService(
    quantity: number,
  ): Promise<IncentiveSettingEntity | null> {
    const queryBuilder =
      this.incentiveSettingReposiory.createQueryBuilder('incentiveSetting');

    queryBuilder.where('incentiveSetting.name = :name', {
      name: IncentiveName.LONG_SERVICE,
    });

    queryBuilder.andWhere('incentiveSetting.threshold <= :quantity', {
      quantity,
    });
    queryBuilder.orderBy('incentiveSetting.threshold', 'DESC');

    return queryBuilder.getOne();
  }

  async findMany(
    pageOptionsDto: IncentiveSettingPageOptionsDto,
  ): Promise<PageDto<IncentiveSettingDto>> {
    const { id, order } = pageOptionsDto;

    const queryBuilder =
      this.incentiveSettingReposiory.createQueryBuilder('incentiveSetting');

    if (id) {
      queryBuilder.where(`incentiveSetting.id = :id`, { id });
    }

    queryBuilder.orderBy('incentiveSetting.name', order);

    const [items, pageMetaDto] = await queryBuilder.paginate(pageOptionsDto);

    return items.toPageDto(pageMetaDto);
  }

  async findManyWithoutPagination(): Promise<IncentiveSettingEntity[]> {
    const queryBuilder =
      this.incentiveSettingReposiory.createQueryBuilder('incentiveSetting');

    return queryBuilder.getMany();
  }

  async findManyDropdown(
    showInactive = false,
  ): Promise<Array<{ name: string; value: string | null }>> {
    const queryBuilder =
      this.incentiveSettingReposiory.createQueryBuilder('incentiveSetting');

    queryBuilder.select('DISTINCT incentiveSetting.name', 'name');

    if (!showInactive) {
      queryBuilder.where('incentiveSetting.isActive = :status', {
        status: true,
      });
    }

    queryBuilder.orderBy('incentiveSetting.name', 'ASC');

    const response: Array<{ name: string }> = await queryBuilder.getRawMany();

    const returnData: Array<{ name: string; value: string | null }> =
      response.map((el) => ({
        name: el.name,
        value: el.name,
      }));

    returnData.push({ name: 'None', value: null });

    return returnData;
  }

  async createIncentiveSetting(
    dto: CreateIncentiveSettingDto,
  ): Promise<IncentiveSettingEntity> {
    const incentiveSettingEntity = this.incentiveSettingReposiory.create(dto);
    await this.incentiveSettingReposiory.save(incentiveSettingEntity);

    return incentiveSettingEntity;
  }

  async updateincentiveSetting(
    incentiveSettingEntity: IncentiveSettingEntity,
    dto: UpdateIncentiveSettingDto,
    user: UserEntity,
  ): Promise<IncentiveSettingEntity> {
    const { amount, isActive, threshold, unit } = dto;

    const oldValue = JSON.stringify({ ...incentiveSettingEntity });
    let summaryChanges = 'UPDATE ';

    // if (name) {
    //   incentiveSettingEntity.name = name;
    // }

    if (amount !== undefined) {
      summaryChanges +=
        incentiveSettingEntity.amount === amount
          ? ''
          : `Amount: ${incentiveSettingEntity.amount} -> ${amount}, `;

      incentiveSettingEntity.amount = amount;
    }

    if (isActive !== undefined) {
      summaryChanges +=
        incentiveSettingEntity.isActive === isActive
          ? ''
          : `IsActive: ${incentiveSettingEntity.isActive} -> ${isActive}, `;

      incentiveSettingEntity.isActive = isActive;
    }

    if (threshold !== undefined) {
      summaryChanges +=
        incentiveSettingEntity.threshold === threshold
          ? ''
          : `Threshold: ${incentiveSettingEntity.threshold} -> ${threshold}, `;

      incentiveSettingEntity.threshold = threshold;
    }

    if (unit !== undefined) {
      summaryChanges +=
        incentiveSettingEntity.unit === unit
          ? ''
          : `Unit: ${incentiveSettingEntity.unit} -> ${unit}, `;

      incentiveSettingEntity.unit = unit;
    }

    // if (type) {
    //   incentiveSettingEntity.type = type;
    // }

    const updatedEntity = await this.incentiveSettingReposiory.save(
      incentiveSettingEntity,
    );

    await this.auditLogService.create({
      itemId: updatedEntity.id,
      newValue: JSON.stringify(updatedEntity),
      oldValue,
      operateType: OperateType.UPDATE,
      summaryChanges,
      tableName: 'incentiveSetting',
      user,
    });

    return incentiveSettingEntity;
  }
}