import { BadRequestException, Inject, Injectable } from '@nestjs/common'; import { EntityServiceImpl } from 'src/module/meta/service/entity-service-impl.service'; import { DataSource } from 'typeorm'; import { WorkflowRepository } from '../repository/workflow.repository'; import { BaseEntity } from 'src/module/meta/entity/base-entity.entity'; import { UserData } from 'src/module/user/entity/user.entity'; import { ListMasterService } from 'src/module/listmaster/service/list-master.service'; import { STATUS_INACTIVE, WORKFLOW } from 'src/constant/global.constant'; import { Workflow } from '../entity/workflow.entity'; import { StageGroupRepository } from '../repository/stage-group.repository'; import { StageGroupService } from './stage-group.service'; @Injectable() export class WorkflowService extends EntityServiceImpl { constructor( private readonly dataSource: DataSource, private readonly workflowRepository: WorkflowRepository, @Inject('ListMasterService') private readonly listMasterService: ListMasterService, @Inject('StageGroupService') private readonly stateGroupService: StageGroupService, ) { super(); } async getAllWorkflows( entity_type: string, level_id: string, level_type: string, ) { return this.workflowRepository.getAllWorkflowsByFilters( entity_type, level_id, level_type, ); } async getWorkflowById(id: number) { const workflowMasterRepo = this.reflectionHelper.getRepoService('Workflow'); return await workflowMasterRepo.findOne({ where: { id: id } }); } //update entity async updateEntity( entityData: BaseEntity, loggedInUser: UserData, ): Promise { const resolveStatus = await this.listMasterService.getResolvedListCode( STATUS_INACTIVE, loggedInUser?.organization_id || 0, ); const workflowId = entityData.id; const { level_id, level_type, organization_id } = loggedInUser; // Handle INACTIVE status validation if (entityData.status == resolveStatus.id) { const existingWorkflow = (await this.getEntityData( WORKFLOW, workflowId, loggedInUser, )) as Workflow; if (!existingWorkflow) { return { success: false, error: 'Workflow not found' }; } if (existingWorkflow.is_default) { return { success: false, error: 'Cannot inactivate because it is default.', }; } if (existingWorkflow.is_factory) { return { success: false, error: 'Cannot inactivate because it is factory.', }; } } const isDefault = [true, 1, 'true'].includes( (entityData as any).is_default, ); // Handle is_default uniqueness logic within same level if (isDefault) { await this.dataSource .createQueryBuilder() .update(Workflow) .set({ is_default: 0 }) .where( 'level_id = :level_id AND level_type = :level_type AND id != :currentId', { level_id, level_type, currentId: workflowId, }, ) .execute(); await this.reflectionHelper .getRepoService('WorkflowLevelMappingEntity') .update( { mapped_level_id: level_id, mapped_level_type: level_type, }, { workflow_id: workflowId, }, ); } // Final update return super.updateEntity(entityData, loggedInUser); } async deleteWorkflowById(id: number) { return this.workflowRepository.deleteWorkflowById(id); } async deleteEntity( entityType: string, id: number, loggedInUser: UserData, ): Promise { const getWorkflow = await this.getEntityData(entityType, id, loggedInUser); if (!getWorkflow) { throw new BadRequestException('Workflow not found'); } if ((getWorkflow as Workflow).is_default) { throw new BadRequestException( 'Cannot delete workflow because it is default.', ); } if ((getWorkflow as Workflow).is_factory) { throw new BadRequestException( 'Cannot delete workflow because it is factory.', ); } const stageGroupRepo = this.reflectionHelper.getRepoService('StageGroup'); const getAllStageGroup = await stageGroupRepo.find({ where: { workflow_id: id, level_id: loggedInUser.level_id, level_type:loggedInUser.level_type } }); if (getAllStageGroup.length > 0) { for (const stageGroup of getAllStageGroup) { await this.stateGroupService.deleteEntity( 'WFSG', stageGroup.id, loggedInUser, ); } } const deleteWorkflow = await super.deleteEntity( entityType, id, loggedInUser, ); return deleteWorkflow; } async updateSequence(body: any[], loggedInUser: any) { if (!Array.isArray(body) || body.length === 0) { throw new BadRequestException( 'Invalid input. Expected a non-empty array.', ); } const results: { id: any; success: boolean; result?: any; error?: string; }[] = []; for (const item of body) { if (!item.id || item.sequence === undefined) { results.push({ id: item.id || null, success: false, error: 'Missing id or sequence', }); continue; } try { const result = await super.updateEntity(item, loggedInUser); results.push({ id: item.id, success: true, result }); } catch (err) { results.push({ id: item.id, success: false, error: err.message }); } } return { updated: results.filter((r) => r.success).length, results }; } }