import { forwardRef, Inject, Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { type FindOptionsWhere, Repository } from 'typeorm'; import { type PageDto } from '../../common/dto/page.dto'; import { OperateType } from '../../constants'; import { ActivityGroupInUsedException, DuplicateActivityGroupException, } from '../../exceptions'; import { AuditLogService } from '../audit-log/audit-log.service'; import { type UserEntity } from '../user/user.entity'; import { ActivityGroupEntity } from './activity-group.entity'; import { ActivityRecordSettingService } from './activity-record-setting.service'; import { type ActivityGroupDto } from './dtos/activity-group.dto'; import { type CreateActivityGroupDto } from './dtos/create-activity-group.dto'; import { type ActivityGroupPageOptionsDto } from './dtos/get-activity-group-page.dto'; import { type UpdateActivityGroupDto } from './dtos/update-activity-group.dto'; @Injectable() export class ActivityGroupService { constructor( @InjectRepository(ActivityGroupEntity) private activityGroupRepository: Repository, @Inject(forwardRef(() => ActivityRecordSettingService)) private activitySettingService: ActivityRecordSettingService, private auditLogService: AuditLogService, ) {} async findOne( findData: FindOptionsWhere, ): Promise { const queryBuilder = this.activityGroupRepository.createQueryBuilder('activityGroup'); queryBuilder.where(findData); return queryBuilder.getOne(); } async findMany( pageOptionsDto: ActivityGroupPageOptionsDto, ): Promise> { const { name, id } = pageOptionsDto; const queryBuilder = this.activityGroupRepository.createQueryBuilder('activityGroup'); if (name !== undefined) { queryBuilder.andWhere('activityGroup.name ILIKE :name', { name: `%${name}%`, }); } if (id !== undefined) { queryBuilder.andWhere('activityGroup.id = :id', { id }); } const [items, pageMetaDto] = await queryBuilder.paginate(pageOptionsDto); return items.toPageDto(pageMetaDto); } async findManyDropdown(): Promise> { const queryBuilder = this.activityGroupRepository.createQueryBuilder('activityGroup'); queryBuilder.orderBy('activityGroup.name', 'ASC'); const returnData = await queryBuilder.getMany(); return returnData.map((el) => ({ name: el.name, value: el.name, })); } async create( dto: CreateActivityGroupDto, user: UserEntity, ): Promise { const activityGroupEntity = this.activityGroupRepository.create(dto); const createdActivity = await this.activityGroupRepository.save(activityGroupEntity); await this.auditLogService.create({ itemId: createdActivity.id, newValue: JSON.stringify(createdActivity), oldValue: null, operateType: OperateType.CREATE, summaryChanges: 'CREATE acitivity group', tableName: 'acitivityGroup', user, }); return activityGroupEntity; } async update( activityGroupEntity: ActivityGroupEntity, dto: UpdateActivityGroupDto, user: UserEntity, ): Promise { const { name } = dto; const oldValue = JSON.stringify({ ...activityGroupEntity }); let summaryChanges = 'UPDATE '; if (name !== undefined) { const existingActivityGroup = await this.findOne({ name, }); if (existingActivityGroup) { throw new DuplicateActivityGroupException(); } summaryChanges += activityGroupEntity.name === name ? '' : `Name: ${activityGroupEntity.name} -> ${name}, `; activityGroupEntity.name = name; } const updatedEntity = await this.activityGroupRepository.save(activityGroupEntity); await this.auditLogService.create({ itemId: updatedEntity.id, newValue: JSON.stringify(updatedEntity), oldValue, operateType: OperateType.UPDATE, summaryChanges, tableName: 'activityGroup', user, }); return activityGroupEntity; } async delete( activityGroupEntity: ActivityGroupEntity, user: UserEntity, ): Promise { const existingActivitySetting = await this.activitySettingService.findOne({ activityGroup: { id: activityGroupEntity.id }, }); if (existingActivitySetting) { throw new ActivityGroupInUsedException(); } await this.auditLogService.create({ itemId: activityGroupEntity.id, newValue: null, oldValue: JSON.stringify(activityGroupEntity), operateType: OperateType.DELETE, summaryChanges: 'DELETE activity group', tableName: 'activityGroup', user, }); await this.activityGroupRepository.remove(activityGroupEntity); } }