113 lines
4.3 KiB
TypeScript
113 lines
4.3 KiB
TypeScript
import { Injectable, NotFoundException } from '@nestjs/common';
|
|
import { CreateCategoryDto } from '../dto/create-category.dto';
|
|
import { UpdateCategoryDto } from '../dto/update-category.dto';
|
|
import { CategoryRepository } from '../repositories/category.repository';
|
|
import { EntityManager } from '@mikro-orm/postgresql';
|
|
import { RequiredEntityData } from '@mikro-orm/core';
|
|
import { Category } from '../entities/category.entity';
|
|
import { CategoryMessage, RestMessage } from 'src/common/enums/message.enum';
|
|
import { Restaurant } from 'src/modules/restaurants/entities/restaurant.entity';
|
|
|
|
@Injectable()
|
|
export class CategoryService {
|
|
constructor(
|
|
private readonly categoryRepository: CategoryRepository,
|
|
private readonly em: EntityManager,
|
|
) { }
|
|
|
|
async create(restId: string, dto: CreateCategoryDto): Promise<Category> {
|
|
const restaurant = await this.em.findOne(Restaurant, { id: restId });
|
|
if (!restaurant) {
|
|
throw new NotFoundException(RestMessage.NOT_FOUND);
|
|
}
|
|
const data: RequiredEntityData<Category> = {
|
|
title: dto.title,
|
|
isActive: dto.isActive ?? true,
|
|
restaurant: restaurant,
|
|
avatarUrl: dto.avatarUrl,
|
|
};
|
|
|
|
const category = this.categoryRepository.create(data);
|
|
await this.em.persistAndFlush(category);
|
|
return category;
|
|
}
|
|
|
|
async findAllByRestaurant(slug: string): Promise<Category[]> {
|
|
const restaurant = await this.em.findOne(Restaurant, { slug });
|
|
if (!restaurant || !restaurant.id) {
|
|
throw new NotFoundException(RestMessage.NOT_FOUND);
|
|
}
|
|
return this.categoryRepository.find(
|
|
{ restaurant: restaurant, isActive: true }, { orderBy: { order: 'ASC' } });
|
|
}
|
|
|
|
async findAllByRestaurantId(restId: string): Promise<Category[]> {
|
|
return this.categoryRepository.find({ restaurant: { id: restId } });
|
|
}
|
|
|
|
// async findAll(opts?: { restId?: string; isActive?: boolean }): Promise<Category[]> {
|
|
// const where: FilterQuery<Category> = {};
|
|
// if (opts?.restId) where.restId = opts.restId;
|
|
// if (opts && typeof opts.isActive === 'boolean') where.isActive = opts.isActive;
|
|
// const cats = await this.categoryRepository.find(where, { populate: ['foods'] });
|
|
|
|
// // Return plain objects to avoid circular references during JSON serialization
|
|
// return cats.map(cat => ({
|
|
// id: cat.id,
|
|
// title: cat.title,
|
|
// isActive: cat.isActive,
|
|
// restId: cat.restId,
|
|
// avatarUrl: cat.avatarUrl,
|
|
// createdAt: cat.createdAt,
|
|
// updatedAt: cat.updatedAt,
|
|
// foods: cat.foods.getItems().map(f => ({ id: f.id, title: f.title })),
|
|
// })) as unknown as Category[];
|
|
// }
|
|
|
|
async findOne(restId: string, id: string): Promise<Category> {
|
|
const cat = await this.categoryRepository.findOne({ id, restaurant: { id: restId } }, { populate: ['foods'] });
|
|
if (!cat) throw new NotFoundException(CategoryMessage.NOT_FOUND);
|
|
|
|
return {
|
|
id: cat.id,
|
|
title: cat.title,
|
|
isActive: cat.isActive,
|
|
restaurant: cat.restaurant,
|
|
avatarUrl: cat.avatarUrl,
|
|
createdAt: cat.createdAt,
|
|
updatedAt: cat.updatedAt,
|
|
foods: cat.foods.getItems().map(f => ({ id: f.id, title: f.title })),
|
|
} as unknown as Category;
|
|
}
|
|
|
|
async findRestaurantCategories(restId: string): Promise<Category> {
|
|
const cat = await this.categoryRepository.findOne({ restaurant: { id: restId } }, { populate: ['foods'] });
|
|
if (!cat) throw new NotFoundException(CategoryMessage.NOT_FOUND);
|
|
|
|
return {
|
|
id: cat.id,
|
|
title: cat.title,
|
|
isActive: cat.isActive,
|
|
restaurant: cat.restaurant,
|
|
avatarUrl: cat.avatarUrl,
|
|
createdAt: cat.createdAt,
|
|
updatedAt: cat.updatedAt,
|
|
} as unknown as Category;
|
|
}
|
|
|
|
async update(restId: string, id: string, dto: UpdateCategoryDto): Promise<Category> {
|
|
const cat = await this.categoryRepository.findOne({ id, restaurant: { id: restId } });
|
|
if (!cat) throw new NotFoundException(CategoryMessage.NOT_FOUND);
|
|
this.em.assign(cat, dto);
|
|
await this.em.persistAndFlush(cat);
|
|
return cat;
|
|
}
|
|
|
|
async remove(restId: string, id: string): Promise<void> {
|
|
const cat = await this.categoryRepository.findOne({ id, restaurant: { id: restId } });
|
|
if (!cat) throw new NotFoundException(CategoryMessage.NOT_FOUND);
|
|
cat.deletedAt = new Date();
|
|
await this.em.persistAndFlush(cat);
|
|
}
|
|
}
|