import { EntityService } from './entity.service'; import { BadRequestException, forwardRef, Inject, Injectable, NotFoundException } from '@nestjs/common'; import { UserData } from '../../user/entity/user.entity'; import { EntityMasterService } from './entity-master.service'; import { ReflectionHelper } from '../../../utils/service/reflection-helper.service'; import { BaseEntity } from '../entity/base-entity.entity'; import { LoggingService } from '../../../utils/service/loggingUtil.service'; import { EntityManager } from 'typeorm'; import { EntityTableService } from './entity-table.service'; import { EntityTableColumnService } from './entity-table-column.service'; import { ENTITYTYPE_ENTITYMASTER, STATUS_ACTIVE } from '../../../constant/global.constant'; import { EntityValidationService } from './entity-validation.service'; import { ResolverService } from './resolver.service'; @Injectable() export class EntityServiceImpl implements EntityService { @Inject() protected readonly entityMasterService: EntityMasterService; @Inject() protected readonly entityTableColumnService: EntityTableColumnService; @Inject() protected readonly entityTableService: EntityTableService; @Inject() protected readonly reflectionHelper: ReflectionHelper; @Inject() protected readonly loggingService: LoggingService; @Inject() protected readonly entityValidationService: EntityValidationService; @Inject(forwardRef(() => ResolverService)) protected readonly resolverService: ResolverService; async createEntity( entityData: BaseEntity, loggedInUser: UserData | null, manager?: EntityManager | null, appcode?: string, ) { if (!entityData.entity_type) { throw new BadRequestException(`EntityType is missing`); } const entityMaster = await this.entityMasterService.getEntityData( entityData.entity_type, loggedInUser, ); const validationErrors = await this.entityValidationService.validateEntityData( entityData, entityMaster, loggedInUser, ); console.log('Validation Errors:', validationErrors); // Debug log if (validationErrors && validationErrors.length > 0) { return { success: false, message: 'Validation failed', errors: validationErrors, }; } const repo = manager ? manager.getRepository(entityMaster.entity_data_class) // <-- Use transaction-safe repo : this.reflectionHelper.getRepoService(entityMaster.entity_data_class); if (!repo) { throw new Error( `Repository service not found for entityType: ${entityData.entity_type}`, ); } if (!entityData.code && loggedInUser) { let maxSeqNo = await this.getMaxSequenceNumber( entityData.entity_type, loggedInUser, ); maxSeqNo = Number(maxSeqNo) + 1; entityData.code = entityData.entity_type + maxSeqNo; } const listMasterItemsRepo = this.reflectionHelper.getRepoService('ListMasterItems'); const statusList = await listMasterItemsRepo.findOne({ where: { code: STATUS_ACTIVE, organization_id: loggedInUser?.organization_id || 0, }, select: ['id'], }); console.log('Status List:', statusList); // Debug log console.log( `status_code,${STATUS_ACTIVE},statusList, ${loggedInUser?.organization_id}`, ); // Debug log entityData.created_date = new Date(); if (loggedInUser) { entityData.created_by = loggedInUser.id; if (!entityData.organization_id) entityData.organization_id = loggedInUser.organization_id; if (!entityData.enterprise_id) entityData.enterprise_id = loggedInUser.enterprise_id; if (!entityData.level_type) entityData.level_type = loggedInUser.level_type; if (!entityData.level_id) entityData.level_id = loggedInUser.level_id; if (!entityData.status) entityData.status = statusList.id; } let savedData = repo.save(entityData); return savedData; } async deleteEntity(entityType: string, entityId: number, loggedInUser) { const entityMaster = await this.entityMasterService.getEntityData( entityType, loggedInUser, ); const repoService = this.reflectionHelper.getRepoService( entityMaster.entity_data_class, ); if (!repoService) { throw new Error( `Repository service not found for entityType: ${entityType}`, ); } const entityData = await repoService.findOne({ where: { id: entityId } }); if (!entityData) { throw new Error(`Entity not found for entityType: ${entityType}`); } await repoService.delete(entityId); return { success: true, message: `Entity with id ${entityId} deleted successfully.`, }; } async findByCode( entityType: string, code: string, loggedInUser, ): Promise { const entityData = await this.entityMasterService.getEntityData( entityType, loggedInUser, ); const repoService = this.reflectionHelper.getRepoService( entityData.entity_data_class, ); if (!repoService) { throw new Error( `Repository service not found for entityType: ${entityType}`, ); } const result = await repoService?.findOne({ where: { code: code } }); if (!result) { throw new Error(`Entity not found for entityType: ${entityType}`); } return result; } async getEntityData( entityType: string, id: number, loggedInUser, ): Promise { const entityData = await this.entityMasterService.getEntityData( entityType, loggedInUser, ); const repoService = this.reflectionHelper.getRepoService( entityData.entity_data_class, ); if (!repoService) { throw new Error( `Repository service not found for entityType: ${entityType}`, ); } return await repoService.findOne({ where: { id: id } }); } async getEntityDataAll( entityType: string, type: {}, loggedInUser: UserData, ): Promise { const entityData = await this.entityMasterService.getEntityData( entityType, loggedInUser, ); const repoService = this.reflectionHelper.getRepoService( entityData.entity_data_class, ); if (!repoService) { throw new Error( `Repository service not found for entityType: ${entityType}`, ); } return await repoService.find({ where: type }); } async getEntityDataByCode( entityType: string, code: string, loggedInUser: UserData, ): Promise { const entityData = await this.entityMasterService.getEntityData( entityType, loggedInUser, ); const repoService = this.reflectionHelper.getRepoService( entityData.entity_data_class, ); if (!repoService) { throw new BadRequestException( `Repository service not found for entityType: ${entityType}`, ); } const data = await repoService.findOne({ where: { code: code } }); if (!data) { throw new NotFoundException(`Data not found for Code: ${code}`); } return data; } async getEntityList( entityType: string, filters: Record = {}, loggedInUser: UserData, ): Promise { const entityData = await this.entityMasterService.getEntityData( entityType, loggedInUser, ); const repoService = this.reflectionHelper.getRepoService( entityData.entity_data_class, ); if (!repoService) { throw new Error( `Repository service not found for entityType: ${entityType}`, ); } const result = await repoService.find({ where: filters, }); return result; } async updateEntity( entityData: BaseEntity, loggedInUser: UserData, appcode?: string, ) { const entityMaster = await this.entityMasterService.getEntityData( entityData.entity_type, loggedInUser, ); const validationErrors = await this.entityValidationService.validateEntityData( entityData, entityMaster, loggedInUser, ); console.log('Validation Errors For Update:', validationErrors); // Debug log if (validationErrors && validationErrors.length > 0) { return { success: false, message: 'Validation failed', errors: validationErrors, }; } const repoService = this.reflectionHelper.getRepoService( entityMaster.entity_data_class, ); if (!repoService) { throw new Error( `Repository service not found for entityType: ${entityData.entity_type}`, ); } entityData.modified_date = new Date(); if (loggedInUser) { entityData.modified_by = loggedInUser.id; if (!entityData.organization_id && entityData.entity_type !== 'ORG') entityData.organization_id = loggedInUser.organization_id; if (!entityData.enterprise_id) entityData.enterprise_id = loggedInUser.enterprise_id; } await repoService.update(entityData.id, entityData); return await repoService.findOne({ where: { id: entityData.id } }); } private async getMaxSequenceNumber( entityType: string, loggedInUser: UserData, ): Promise { let repo; if (ENTITYTYPE_ENTITYMASTER === entityType) { repo = this.reflectionHelper.getRepoService('EntityMaster'); } else { const entityMaster = await this.entityMasterService.getEntityData( entityType, loggedInUser, ); repo = this.reflectionHelper.getRepoService(entityMaster.entity_data_class); } const result = await repo .createQueryBuilder() .select('MAX(id)', 'seq_no') .getRawOne(); const seqNo = result?.seq_no ?? 0; return seqNo; } async getSingleResolvedData( loggedInUser: UserData, entityData: any, entityType: string, ): Promise { return this.resolverService.getResolvedData( loggedInUser, entityData, entityType, ); } async getResolvedEntityData( entityType: string, entityId: number, loggedInUser: UserData, ): Promise { const entityData = await this.entityMasterService.getEntityData( entityType, loggedInUser, ); const repoService = this.reflectionHelper.getRepoService( entityData.entity_data_class, ); if (!repoService) { throw new Error( `Repository service not found for entityType: ${entityType}`, ); } const data = await repoService.findOne({ where: { id: entityId } }); return this.resolverService.getResolvedData(loggedInUser, data, entityType); } async getResolvedEntityDataByDataSource( entityType: string, entityId: number, loggedInUser: UserData, ): Promise { const entityData = await this.entityMasterService.getEntityData( entityType, loggedInUser, ); if (!entityData.data_source) { throw new Error('Database table name is missing in entity master.'); } const data = await this.reflectionHelper.getEntityData( entityId, entityData.data_source, ); return this.resolverService.getResolvedData(loggedInUser, data, entityType); } }