import { ConflictException, Injectable, NotFoundException } from '@nestjs/common'; import { Admin } from '../entities/admin.entity'; import { Role } from '../../roles/entities/role.entity'; import { EntityManager, RequiredEntityData } from '@mikro-orm/postgresql'; import { UpdateAdminDto } from '../dto/update-admin.dto'; import { normalizePhone } from '../../util/phone.util'; import { CreateAdminDto } from '../dto/create-admin.dto'; import { AdminRepository } from '../repositories/admin.repository'; import { RoleRepository } from 'src/modules/roles/respository/role.repository'; @Injectable() export class AdminService { constructor( private readonly adminRepository: AdminRepository, private readonly roleRepository: RoleRepository, private readonly em: EntityManager, ) { } async create(dto: CreateAdminDto) { const { phone, firstName, lastName, roleId } = dto; const normalizedPhone = normalizePhone(phone); const exist = await this.adminRepository.findOne({ phone: normalizedPhone, }); if (exist) { throw new NotFoundException('This phone number is already used'); } const role = await this.roleRepository.findOne({ id: roleId }) if (!role) { throw new NotFoundException('Role not found'); } const createData: RequiredEntityData = { phone: normalizedPhone, firstName, lastName, role } const admin = this.adminRepository.create(createData) await this.em.persistAndFlush(admin); return admin; } async findByPhone(phone: string): Promise { const normalizedPhone = normalizePhone(phone); return this.adminRepository.findOne({ phone: normalizedPhone }); } async findById(adminId: string): Promise { const admin = await this.adminRepository.findOne( { id: adminId }, { populate: ['role'] }, ); return admin; } async findAll(): Promise { return this.adminRepository.find({}, { populate: ['role'] }); } async update(adminId: string, dto: UpdateAdminDto): Promise { const admin = await this.adminRepository.findOne( { id: adminId }, { populate: ['role'] }, ); if (!admin) { throw new NotFoundException('Admin not found'); } const { roleId, ...rest } = dto; // Update scalar fields (firstName, lastName, phone) if (rest.firstName !== undefined) { admin.firstName = rest.firstName; } if (rest.lastName !== undefined) { admin.lastName = rest.lastName; } if (rest.phone !== undefined && rest.phone !== admin.phone) { const normalizedPhone = normalizePhone(rest.phone); const exists = await this.adminRepository.findOne({ phone: normalizedPhone }); if (exists) { throw new ConflictException('This Phone Number is already taken'); } admin.phone = normalizedPhone; } // Update role if roleId is provided if (roleId) { const role = await this.em.findOne(Role, { id: roleId, isSystem: false }); if (!role) { throw new NotFoundException('Role not found'); } admin.role = role } await this.em.persistAndFlush(admin); return admin; } async remove(adminId: string): Promise { const admin = await this.adminRepository.findOne({ id: adminId }); if (!admin) { throw new NotFoundException('Admin role not found'); } // admin.deletedAt=new Date() // TODO :L is this correct to soft delete return this.em.removeAndFlush(admin); } }