118 lines
4.0 KiB
TypeScript
118 lines
4.0 KiB
TypeScript
import { Injectable, NotFoundException } from '@nestjs/common';
|
|
import { CreateFoodDto } from '../dto/create-food.dto';
|
|
import { FindFoodsDto } from '../dto/find-foods.dto';
|
|
import { FoodRepository } from '../repositories/food.repository';
|
|
import { CategoryRepository } from '../repositories/category.repository';
|
|
import { EntityManager } from '@mikro-orm/postgresql';
|
|
import { RequiredEntityData } from '@mikro-orm/core';
|
|
import { Food } from '../entities/food.entity';
|
|
import { CategoryMessage, FoodMessage, RestMessage } from 'src/common/enums/message.enum';
|
|
import { RestRepository } from 'src/modules/restaurants/repositories/rest.repository';
|
|
|
|
@Injectable()
|
|
export class FoodService {
|
|
constructor(
|
|
private readonly foodRepository: FoodRepository,
|
|
private readonly categoryRepository: CategoryRepository,
|
|
private readonly restRepository: RestRepository,
|
|
private readonly em: EntityManager,
|
|
) {}
|
|
|
|
async create(restId: string, createFoodDto: CreateFoodDto): Promise<Food> {
|
|
const { categoryId, ...rest } = createFoodDto;
|
|
const restaurant = await this.restRepository.findOne({ id: restId });
|
|
if (!restaurant) {
|
|
throw new NotFoundException(RestMessage.NOT_FOUND);
|
|
}
|
|
const category = await this.categoryRepository.findOne({ id: categoryId });
|
|
if (!category) {
|
|
throw new NotFoundException(CategoryMessage.NOT_FOUND);
|
|
}
|
|
|
|
// prepare data with defaults for required fields so repository.create typing is satisfied
|
|
const data: RequiredEntityData<Food> = {
|
|
// boolean/day flags
|
|
sat: rest.sat ?? false,
|
|
sun: rest.sun ?? false,
|
|
mon: rest.mon ?? false,
|
|
breakfast: rest.breakfast ?? false,
|
|
noon: rest.noon ?? false,
|
|
dinner: rest.dinner ?? false,
|
|
// pickup/stock
|
|
stock: rest.stock ?? 0,
|
|
stockDefault: rest.stockDefault ?? 0,
|
|
isActive: rest.isActive ?? true,
|
|
inPlaceServe: rest.inPlaceServe ?? false,
|
|
pickupServe: rest.pickupServe ?? false,
|
|
discount: rest.discount ?? 0,
|
|
// map single-title/content DTO to localized fields
|
|
title: rest.title,
|
|
content: rest.content,
|
|
// numeric/array fields
|
|
price: rest.price ?? 0,
|
|
points: rest.points ?? 0,
|
|
prepareTime: rest.prepareTime ?? 0,
|
|
images: rest.images ?? undefined,
|
|
restaurant: restaurant,
|
|
category: category
|
|
};
|
|
|
|
const food = this.foodRepository.create(data);
|
|
if (!food) {
|
|
throw new Error('Failed to create food entity');
|
|
}
|
|
|
|
await this.em.persistAndFlush(food);
|
|
return food;
|
|
}
|
|
|
|
findAll(restId: string, dto: FindFoodsDto) {
|
|
return this.foodRepository.findAllPaginated(restId, dto);
|
|
}
|
|
|
|
async findById(id: string): Promise<Food> {
|
|
const food = await this.foodRepository.findOne({ id }, { populate: ['category'] });
|
|
if (!food) {
|
|
throw new NotFoundException(FoodMessage.NOT_FOUND);
|
|
}
|
|
return food;
|
|
}
|
|
|
|
async findAllByRestaurant(slug: string): Promise<Food[]> {
|
|
const restaurant = await this.restRepository.findOne({ slug });
|
|
if (!restaurant) {
|
|
throw new NotFoundException(RestMessage.NOT_FOUND);
|
|
}
|
|
return this.foodRepository.find({ restaurant: { slug }, isActive: true }, { populate: ['category'] });
|
|
}
|
|
|
|
async update(id: string, dto: Partial<CreateFoodDto>): Promise<Food> {
|
|
const food = await this.foodRepository.findOne({ id });
|
|
if (!food) {
|
|
throw new NotFoundException(FoodMessage.NOT_FOUND);
|
|
}
|
|
// attach new categories if provided (adds, does not attempt to preserve/remove existing ones)
|
|
if (dto.categoryId) {
|
|
const category = await this.categoryRepository.findOne({ id: dto.categoryId });
|
|
|
|
if (!category) {
|
|
throw new NotFoundException(CategoryMessage.NOT_FOUND);
|
|
}
|
|
|
|
this.em.assign(food, { category: category });
|
|
}
|
|
|
|
await this.em.persistAndFlush(food);
|
|
return food;
|
|
}
|
|
|
|
async remove(id: string) {
|
|
const food = await this.foodRepository.findOne({ id });
|
|
if (!food) {
|
|
throw new NotFoundException(FoodMessage.NOT_FOUND);
|
|
}
|
|
food.deletedAt = new Date();
|
|
await this.em.persistAndFlush(food);
|
|
}
|
|
}
|