Files
dkala-api/src/modules/admin/providers/admin.service.ts
T
2026-02-08 09:18:20 +03:30

198 lines
6.4 KiB
TypeScript

import { ConflictException, Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@mikro-orm/nestjs';
import { EntityRepository } from '@mikro-orm/core';
import { Admin } from '../entities/admin.entity';
import { Role } from '../../../roles/entities/role.entity';
import { Shop } from ../../..shops/entities/shop.entity';
import { EntityManager } from '@mikro-orm/postgresql';
import { CacheService } from '../../../utils/cache.service';
import { CreateMyRestaurantAdminDto } from '../dto/create-my-shop-admin.dto';
import { UpdateAdminDto } from '../dto/update-admin.dto';
import { AdminRole } from '../entities/adminRole.entity';
import { normalizePhone } from '../../../utils/phone.util';
@Injectable()
export class AdminService {
constructor(
@InjectRepository(Admin)
private readonly adminRepository: EntityRepository<Admin>,
@InjectRepository(AdminRole)
private readonly adminRoleRepository: EntityRepository<AdminRole>,
private readonly em: EntityManager,
private readonly cacheService: CacheService,
) {}
async findByPhone(phone: string): Promise<Admin | null> {
const normalizedPhone = normalizePhone(phone);
return this.adminRepository.findOne({ phone: normalizedPhone });
}
async findById(adminId: string, restId: string): Promise<Admin | null> {
const admin = await this.adminRepository.findOne(
{ id: adminId, roles: { shop: { id: restId } } },
{ populate: ['roles', 'roles.role'] },
);
return admin;
}
async findAllByRestaurantId(restId: string): Promise<Admin[]> {
return this.adminRepository.find({ roles: { shop: { id: restId } } }, { populate: ['roles', 'roles.role'] });
}
async createAdminForMyRestaurant(restId: string, dto: CreateMyRestaurantAdminDto) {
const { phone, firstName, lastName, roleId } = dto;
const normalizedPhone = normalizePhone(phone);
let admin: Admin | null = null;
admin = await this.adminRepository.findOne({
phone: normalizedPhone,
});
if (!admin) {
admin = this.adminRepository.create({
phone: normalizedPhone,
firstName,
lastName,
});
await this.em.persistAndFlush(admin);
}
const role = await this.em.findOne(Role, { id: roleId, isSystem: false });
if (!role) throw new NotFoundException('Role not found');
const shop = await this.em.findOne(Shop, { id: restId });
if (!shop) throw new NotFoundException('Shop not found');
let adminRole = await this.adminRoleRepository.findOne({
admin: admin,
shop: shop,
});
if (!adminRole) {
adminRole = this.adminRoleRepository.create({
admin: admin,
role,
shop,
});
} else {
adminRole.role = role;
}
await this.em.persistAndFlush(adminRole);
return admin;
}
async createAdminForRestaurantBySuperAdmin(restId: string, dto: CreateMyRestaurantAdminDto) {
const { phone, firstName, lastName, roleId } = dto;
const normalizedPhone = normalizePhone(phone);
let admin: Admin | null = null;
admin = await this.adminRepository.findOne({
phone: normalizedPhone,
});
if (!admin) {
admin = this.adminRepository.create({
phone: normalizedPhone,
firstName,
lastName,
});
await this.em.persistAndFlush(admin);
}
const role = await this.em.findOne(Role, { id: roleId });
if (!role) throw new NotFoundException('Role* not found' + roleId);
const shop = await this.em.findOne(Shop, { id: restId });
if (!shop) throw new NotFoundException('Shop not found');
let adminRole = await this.adminRoleRepository.findOne({
admin: admin,
shop: shop,
});
if (!adminRole) {
adminRole = this.adminRoleRepository.create({
admin: admin,
role,
shop,
});
} else {
adminRole.role = role;
}
await this.em.persistAndFlush(adminRole);
return admin;
}
async getAdminsForRestaurantBySuperAdmin(restId: string): Promise<Admin[]> {
const shop = await this.em.findOne(Shop, { id: restId });
if (!shop) throw new NotFoundException('Shop not found');
return this.adminRepository.find({ roles: { shop: shop } }, { populate: ['roles', 'roles.role'] });
}
async update(adminId: string, restId: string, dto: UpdateAdminDto): Promise<Admin> {
const admin = await this.adminRepository.findOne(
{ id: adminId, roles: { shop: { id: restId } } },
{ populate: ['roles', 'roles.role', 'roles.shop'] },
);
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');
}
// Find existing AdminRole for this admin and shop
const existingAdminRole = await this.em.findOne(AdminRole, {
admin: { id: adminId },
shop: { id: restId },
});
if (existingAdminRole) {
// Update existing role
existingAdminRole.role = role;
} else {
const shop = await this.em.findOne(Shop, { id: restId });
if (!shop) throw new NotFoundException('Shop not found');
// Create new AdminRole
const newAdminRole = this.em.create(AdminRole, {
admin,
role,
shop,
});
admin.roles.add(newAdminRole);
}
}
await this.em.persistAndFlush(admin);
return admin;
}
async remove(adminId: string, restId: string): Promise<void> {
const adminRole = await this.adminRoleRepository.findOne({ admin: { id: adminId }, shop: { id: restId } });
if (!adminRole) {
throw new NotFoundException('Admin role not found');
}
return this.em.removeAndFlush(adminRole);
}
}