category
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
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 { Foods } from '../entities/food.entity';
|
||||
import { FoodMessage } from 'src/common/enums/message.enum';
|
||||
|
||||
@Injectable()
|
||||
export class FoodService {
|
||||
constructor(
|
||||
private readonly foodRepository: FoodRepository,
|
||||
private readonly categoryRepository: CategoryRepository,
|
||||
private readonly em: EntityManager,
|
||||
) {}
|
||||
|
||||
async create(createFoodDto: CreateFoodDto): Promise<Foods> {
|
||||
const { categoryIds, ...rest } = createFoodDto;
|
||||
|
||||
// prepare data with defaults for required fields so repository.create typing is satisfied
|
||||
const data: RequiredEntityData<Foods> = {
|
||||
// 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
|
||||
isPickup: rest.isPickup ?? false,
|
||||
stock: rest.stock ?? 0,
|
||||
stockDefault: rest.stockDefault ?? 0,
|
||||
isActive: rest.isActive ?? true,
|
||||
inPlaceServe: rest.inPlaceServe ?? false,
|
||||
pickupServe: rest.pickupServe ?? false,
|
||||
rate: rest.rate ?? 0,
|
||||
discount: rest.discount ?? 0,
|
||||
// map single-title/content DTO to localized fields
|
||||
titleFa: rest.title,
|
||||
contentFa: rest.content,
|
||||
// numeric/array fields
|
||||
price: rest.price ?? 0,
|
||||
points: rest.points ?? 0,
|
||||
prepareTime: rest.prepareTime ?? 0,
|
||||
images: rest.images ?? undefined,
|
||||
} as RequiredEntityData<Foods>;
|
||||
|
||||
const food = this.foodRepository.create(data);
|
||||
|
||||
// attach categories if provided
|
||||
if (categoryIds && categoryIds.length) {
|
||||
const categories = await this.categoryRepository.find({ id: { $in: categoryIds } });
|
||||
categories.forEach(cat => food.categories.add(cat));
|
||||
}
|
||||
|
||||
await this.em.persistAndFlush(food);
|
||||
return food;
|
||||
}
|
||||
|
||||
findAll(dto: FindFoodsDto) {
|
||||
return this.foodRepository.findAllPaginated(dto);
|
||||
}
|
||||
|
||||
findOne(id: string) {
|
||||
return this.foodRepository.findOne({ id }, { populate: ['categories'] });
|
||||
}
|
||||
|
||||
async update(id: string, dto: Partial<CreateFoodDto>): Promise<Foods> {
|
||||
const food = await this.foodRepository.findOne({ id });
|
||||
|
||||
if (!food) {
|
||||
throw new NotFoundException(FoodMessage.NOT_FOUND);
|
||||
}
|
||||
|
||||
const { categoryIds, ...rest } = dto;
|
||||
|
||||
// assign scalar fields
|
||||
this.em.assign(food, rest as Partial<Foods>);
|
||||
|
||||
// attach new categories if provided (adds, does not attempt to preserve/remove existing ones)
|
||||
if (Array.isArray(categoryIds) && categoryIds.length) {
|
||||
const categories = await this.categoryRepository.find({ id: { $in: categoryIds } });
|
||||
categories.forEach(cat => {
|
||||
// Collection.add will ignore duplicates
|
||||
food.categories.add(cat);
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user