import { Injectable } from '@nestjs/common'; import { BaseEntity } from 'src/module/meta/entity/base-entity.entity'; import { EntityServiceImpl } from 'src/module/meta/service/entity-service-impl.service'; import { UserData } from 'src/module/user/entity/user.entity'; import { EntityManager, Repository } from 'typeorm'; import { ActionRepository } from '../repository/action.repository'; import { ActionEntity } from '../entity/action.entity'; import { ActionResourcesMapping } from '../entity/action-resources-mapping.entity'; import { InjectRepository } from '@nestjs/typeorm'; import { StageActionMapping } from '../entity/stage-action-mapping.entity'; import { ActionTemplateMapping } from '../entity/action-template-mapping.entity'; @Injectable() export class ActionService extends EntityServiceImpl { constructor( private readonly actionRepository: ActionRepository, @InjectRepository(ActionResourcesMapping) private readonly actionResourcesMappingRepository: Repository, @InjectRepository(StageActionMapping) private readonly stageActionMappingRepository: Repository, @InjectRepository(ActionTemplateMapping) private readonly actionTemplateMappingRepository: Repository, ) { super(); } async getEntityData( entityType: string, id: number, loggedInUser, ): Promise { const actionData = await super.getEntityData(entityType, id, loggedInUser); if (!actionData) { return null; } let actionResourceMappingRepo = this.reflectionHelper.getRepoService('ActionResourcesMapping'); const result = await actionResourceMappingRepo .createQueryBuilder('arm') .leftJoin( 'frm_wf_stage_action_mapping', 'sam', 'sam.id = arm.stg_act_mapping_id' ) .select([ 'arm.template_code AS template_code', 'arm.form_id AS form_id', ]) .where('sam.action_id = :actionId', { actionId: actionData.id }) .getRawMany(); const templates = result .filter((t) => t.template_code !== null) .map((t) => t.template_code); const form = result.find((f) => f.form_id !== null); return { ...actionData, template: templates, form: form?.form_id ?? null, }; } async createEntity( entityData: BaseEntity, loggedInUser: UserData | null, manager?: EntityManager | null, appcode?: string, ): Promise { const actionData = entityData as any; // 🔧 Remove 'template' array before inserting main action const { template, ...actionWithoutTemplates } = actionData; // Step 1: Create main action entity const action = await super.createEntity(actionWithoutTemplates, loggedInUser); // Step 2: Create stage mapping const stageActionMapping = { action_id: action.id, stage_id: actionData.stage_id, entity_type: 'WFSA', } as any; if (entityData?.organization_id) { stageActionMapping.organization_id = entityData.organization_id; } const stageActionMappingData = await super.createEntity( stageActionMapping, loggedInUser, ); // Step 3: Template mapping (existing) if (Array.isArray(actionData.template) && actionData.template.length > 0) { for (const templateCode of actionData.template) { // ➕ Step 4: Resource mapping for template const resourceMapping = { stg_act_mapping_id: stageActionMappingData.id, template_code: templateCode, type: 'template', entity_type: 'WFAR', } as any; if (entityData?.organization_id) { resourceMapping.organization_id = entityData.organization_id; } await super.createEntity(resourceMapping, loggedInUser); } } await this.actionResourcesMappingRepository.delete({ stg_act_mapping_id: stageActionMappingData.id, type: 'form', }); if (actionData.form) { const resourceMapping = { stg_act_mapping_id: stageActionMappingData.id, organization_id: entityData.organization_id, level_id: entityData.level_id, form_id: actionData.form, type: 'form', entity_type: 'WFAR', } as any; await super.createEntity(resourceMapping, loggedInUser); } return actionData; } async updateEntity( entityData: BaseEntity, loggedInUser: UserData, ): Promise { // Extract template from entityData, keep the rest for ActionEntity const { template, stage_id, form, ...actionData } = entityData as ActionEntity & { template?: number[]; stage_id?: string; form?: number; }; // Pass only actionData (without template) to super.updateEntity const action = await super.updateEntity({ ...actionData }, loggedInUser); if (!action) { throw new Error('Action not found or could not be updated'); } const stageMap = await this.stageActionMappingRepository.findOne({ where: { action_id: action.id, entity_type: 'WFSA', }, }); let stageActionMappingData; if (stageMap) { // Update existing mapping const stageActionMapping = { id: stageMap.id, action_id: action.id, stage_id, entity_type: 'WFSA', } as any; stageActionMappingData = await super.updateEntity( stageActionMapping, loggedInUser, ); } else { // Create new mapping const newStageMapping = { action_id: action.id, stage_id, entity_type: 'WFSA', organization_id: entityData.organization_id, } as any; stageActionMappingData = await super.createEntity( newStageMapping, loggedInUser, ); } // delete existing template mappings for this action await this.actionResourcesMappingRepository.delete({ stg_act_mapping_id: stageActionMappingData.id, type: 'template', }); // Handle template mapping (using the extracted template) if (Array.isArray(template) && template.length > 0) { for (let i = 0; i < template.length; i++) { const templateCode = template[i]; // Create Action-Template Mapping const resourceMapping = { stg_act_mapping_id: stageActionMappingData.id, template_code: templateCode, type: 'template', entity_type: 'WFAR', } as any; const res = await super.createEntity(resourceMapping, loggedInUser); console.log(res); } } await this.actionResourcesMappingRepository.delete({ stg_act_mapping_id: stageActionMappingData.id, type: 'form', }); if (form) { const resourceMapping = { stg_act_mapping_id: stageActionMappingData.id, form_id: form, type: 'form', entity_type: 'WFAR', } as any; await super.createEntity(resourceMapping, loggedInUser); } return action; // Return the action entity instead of actionData } async deleteEntity( entityType: string, id: number, loggedInUser: UserData, ): Promise { await this.actionTemplateMappingRepository .createQueryBuilder() .delete() .where(`stg_act_mapping_id IN ( SELECT sam.id FROM frm_wf_stage_action_mapping sam WHERE sam.action_id = :actionId AND sam.entity_type = 'WFSA' )`) .setParameter('actionId', id) .execute(); await this.stageActionMappingRepository.delete({ action_id: id, entity_type: 'WFSA', }); const deleteAction = await super.deleteEntity(entityType, id, loggedInUser); return deleteAction; } async getReasonCode(loggedInUser: UserData): Promise { return this.actionRepository.getReasonCode(loggedInUser); } async defaultReasonCode(list_type: string, loggedInUser: UserData) { return this.actionRepository.defaultReasonCode(list_type, loggedInUser); } async getActions(loggedInUser: UserData, stage_id: number) { return this.actionRepository.getActions(loggedInUser, stage_id); } async getDependentActions( loggedInUser: UserData, stage_id: number, action_id: number | undefined, ) { return this.actionRepository.getDependentActions( loggedInUser, stage_id, action_id, ); } async getAction( loggedInUser: UserData, stage_id: number, mapped_entity_id: number, mapped_entity_type: string, ) { const { organization_id } = loggedInUser; return this.actionRepository.getAction( organization_id, stage_id, mapped_entity_id, mapped_entity_type, ); } }