161 lines
5.4 KiB
TypeScript
161 lines
5.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 { Restaurant } from '../../restaurants/entities/restaurant.entity';
|
|
import { EntityManager } from '@mikro-orm/postgresql';
|
|
import { CacheService } from '../../utils/cache.service';
|
|
import { CreateMyRestaurantAdminDto } from '../dto/create-my-restaurant-admin.dto';
|
|
import { UpdateAdminDto } from '../dto/update-admin.dto';
|
|
import { AdminRole } from '../entities/adminRole.entity';
|
|
|
|
@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> {
|
|
return this.adminRepository.findOne({ phone });
|
|
}
|
|
|
|
async findById(adminId: string, restId: string): Promise<Admin | null> {
|
|
const admin = await this.adminRepository.findOne(
|
|
{ id: adminId, roles: { restaurant: { id: restId } } },
|
|
{ populate: ['roles', 'roles.role'] },
|
|
);
|
|
return admin;
|
|
}
|
|
|
|
async findAllByRestaurantId(restId: string): Promise<Admin[]> {
|
|
return this.adminRepository.find({ roles: { restaurant: { id: restId } } }, { populate: ['roles', 'roles.role'] });
|
|
}
|
|
|
|
async createAdminForMyRestaurant(restId: string, dto: CreateMyRestaurantAdminDto) {
|
|
const { phone, firstName, lastName, roleId } = dto;
|
|
const currentAdmin = await this.adminRepository.findOne({
|
|
phone,
|
|
});
|
|
if (!currentAdmin) {
|
|
await this.adminRepository.findOne({
|
|
phone,
|
|
firstName,
|
|
lastName,
|
|
});
|
|
}
|
|
const role = await this.em.findOne(Role, { id: roleId });
|
|
if (!role) throw new Error('Role not found');
|
|
|
|
const restaurant = await this.em.findOne(Restaurant, { id: restId });
|
|
if (!restaurant) throw new Error('Restaurant not found');
|
|
const admin = this.adminRepository.create({ phone, firstName, lastName, roles: [{ role, restaurant }] });
|
|
|
|
await this.em.persistAndFlush(admin);
|
|
return admin;
|
|
}
|
|
|
|
async createRestaurantBySuperAdmin(data: {
|
|
phone: string;
|
|
firstName?: string;
|
|
lastName?: string;
|
|
roleId: string;
|
|
restId: string;
|
|
}) {
|
|
const { phone, firstName, lastName, roleId, restId } = data;
|
|
|
|
// check existing
|
|
const existing = await this.adminRepository.findOne({ phone, roles: { restaurant: { id: restId } } });
|
|
if (existing) {
|
|
return existing;
|
|
}
|
|
|
|
// load Role and Restaurant using the EntityManager
|
|
const role = await this.em.findOne(Role, { id: roleId });
|
|
if (!role) throw new Error('Role not found');
|
|
|
|
const restaurant = await this.em.findOne(Restaurant, { id: restId });
|
|
if (!restaurant) throw new Error('Restaurant not found');
|
|
|
|
const admin = this.adminRepository.create({ phone, firstName, lastName, roles: [{ role, restaurant }] });
|
|
await this.em.persistAndFlush(admin);
|
|
return admin;
|
|
}
|
|
|
|
async update(adminId: string, restId: string, dto: UpdateAdminDto): Promise<Admin> {
|
|
const admin = await this.adminRepository.findOne(
|
|
{ id: adminId, roles: { restaurant: { id: restId } } },
|
|
{ populate: ['roles', 'roles.role', 'roles.restaurant'] },
|
|
);
|
|
|
|
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 exists = await this.adminRepository.findOne({ phone: rest.phone });
|
|
if (exists) {
|
|
throw new ConflictException('This Phone Number is already Admin for this restaurant');
|
|
}
|
|
admin.phone = rest.phone;
|
|
}
|
|
|
|
// Update role if roleId is provided
|
|
if (roleId) {
|
|
const role = await this.em.findOne(Role, { id: roleId });
|
|
if (!role) {
|
|
throw new NotFoundException('Role not found');
|
|
}
|
|
|
|
const restaurant = await this.em.findOne(Restaurant, { id: restId });
|
|
if (!restaurant) {
|
|
throw new NotFoundException('Restaurant not found');
|
|
}
|
|
|
|
// Find existing AdminRole for this admin and restaurant
|
|
const existingAdminRole = await this.em.findOne(AdminRole, {
|
|
admin: { id: adminId },
|
|
restaurant: { id: restId },
|
|
});
|
|
|
|
if (existingAdminRole) {
|
|
// Update existing role
|
|
existingAdminRole.role = role;
|
|
} else {
|
|
// Create new AdminRole
|
|
const newAdminRole = this.em.create(AdminRole, {
|
|
admin,
|
|
role,
|
|
restaurant,
|
|
});
|
|
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 }, restaurant: { id: restId } });
|
|
if (!adminRole) {
|
|
throw new NotFoundException('Admin role not found');
|
|
}
|
|
return this.em.removeAndFlush(adminRole);
|
|
}
|
|
}
|