refactor food service
This commit is contained in:
@@ -110,59 +110,75 @@ export class FoodService {
|
||||
return food;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find active foods for a restaurant based on current week day and meal type in Iran timezone.
|
||||
* @param slug - Restaurant slug identifier
|
||||
* @returns Array of active foods matching current day and meal time
|
||||
*/
|
||||
async findByWeekDateAndMealType(slug: string): Promise<Food[]> {
|
||||
// const cacheKey = `${this.FOODS_BY_RESTAURANT_CACHE_KEY_PREFIX}${slug}`;
|
||||
|
||||
// Try to get from cache first
|
||||
// const cachedFoods = await this.cacheService.get<string>(cacheKey);
|
||||
// if (cachedFoods) {
|
||||
// try {
|
||||
// const parsed: unknown = JSON.parse(cachedFoods);
|
||||
// if (Array.isArray(parsed)) {
|
||||
// return parsed as Food[];
|
||||
// }
|
||||
// } catch {
|
||||
// // If parsing fails, continue to fetch from DB
|
||||
// }
|
||||
// }
|
||||
|
||||
// If not in cache, fetch from database
|
||||
const restaurant = await this.restRepository.findOne({ slug });
|
||||
if (!restaurant) {
|
||||
throw new NotFoundException(RestMessage.NOT_FOUND);
|
||||
}
|
||||
const nowInIran = new Date(new Date().toLocaleString('en-US', { timeZone: 'Asia/Tehran' }));
|
||||
|
||||
const { iranWeekDay, mealType } = this.getCurrentIranTimeContext();
|
||||
|
||||
const queryFilter: FilterQuery<Food> = {
|
||||
restaurant: { slug },
|
||||
isActive: true,
|
||||
weekDays: { $contains: iranWeekDay },
|
||||
...(mealType ? { mealTypes: { $contains: mealType } } : {}),
|
||||
} as unknown as FilterQuery<Food>;
|
||||
|
||||
return this.foodRepository.find(queryFilter, { populate: ['category'] });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current Iran timezone context (weekday and meal type).
|
||||
* @returns Object containing Iran weekday (0-6, where 0=Saturday) and current meal type
|
||||
*/
|
||||
private getCurrentIranTimeContext(): { iranWeekDay: number; mealType: MealType | null } {
|
||||
const nowInIran = new Date(new Date().toLocaleString('en-US', { timeZone: 'Asia/Tehran' }));
|
||||
const weekDay = nowInIran.getDay(); // 0 = Sunday, 6 = Saturday
|
||||
const currentHour = nowInIran.getHours();
|
||||
|
||||
// Convert to Iran weekday: Saturday=0, Sunday=1, ..., Friday=6
|
||||
// JavaScript: Sunday=0, Monday=1, ..., Saturday=6
|
||||
// Iran week: Saturday=0, Sunday=1, ..., Friday=6
|
||||
const iranWeekDay = (weekDay + 1) % 7;
|
||||
|
||||
let mealType: string | null = null;
|
||||
if (currentHour >= 6 && currentHour < 11) {
|
||||
mealType = MealType.BREAKFAST;
|
||||
} else if (currentHour >= 11 && currentHour < 15) {
|
||||
mealType = MealType.LUNCH;
|
||||
} else if (currentHour >= 15 && currentHour < 19) {
|
||||
mealType = MealType.SNACK;
|
||||
} else if (currentHour >= 19 && currentHour < 24) {
|
||||
mealType = MealType.DINNER;
|
||||
const mealType = this.getMealTypeByHour(currentHour);
|
||||
|
||||
return { iranWeekDay, mealType };
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine meal type based on current hour in Iran timezone.
|
||||
* @param hour - Current hour (0-23)
|
||||
* @returns Meal type or null if outside meal hours
|
||||
*/
|
||||
private getMealTypeByHour(hour: number): MealType | null {
|
||||
const MEAL_TIME_RANGES = {
|
||||
BREAKFAST: { start: 6, end: 11 },
|
||||
LUNCH: { start: 11, end: 15 },
|
||||
SNACK: { start: 15, end: 19 },
|
||||
DINNER: { start: 19, end: 24 },
|
||||
} as const;
|
||||
|
||||
if (hour >= MEAL_TIME_RANGES.BREAKFAST.start && hour < MEAL_TIME_RANGES.BREAKFAST.end) {
|
||||
return MealType.BREAKFAST;
|
||||
}
|
||||
if (hour >= MEAL_TIME_RANGES.LUNCH.start && hour < MEAL_TIME_RANGES.LUNCH.end) {
|
||||
return MealType.LUNCH;
|
||||
}
|
||||
if (hour >= MEAL_TIME_RANGES.SNACK.start && hour < MEAL_TIME_RANGES.SNACK.end) {
|
||||
return MealType.SNACK;
|
||||
}
|
||||
if (hour >= MEAL_TIME_RANGES.DINNER.start && hour < MEAL_TIME_RANGES.DINNER.end) {
|
||||
return MealType.DINNER;
|
||||
}
|
||||
const foods = await this.foodRepository.find(
|
||||
// cast to FilterQuery<Food> because MikroORM types don't accept a numeric $contains value for jsonb number[]
|
||||
{
|
||||
restaurant: { slug },
|
||||
isActive: true,
|
||||
...(mealType ? { mealTypes: { $contains: mealType } } : {}),
|
||||
weekDays: { $contains: iranWeekDay },
|
||||
} as unknown as FilterQuery<Food>,
|
||||
{ populate: ['category'] },
|
||||
);
|
||||
|
||||
// Cache the result
|
||||
// await this.cacheService.set(cacheKey, JSON.stringify(foods), this.FOODS_CACHE_TTL);
|
||||
|
||||
return foods;
|
||||
return null;
|
||||
}
|
||||
|
||||
async update(restId: string, id: string, dto: Partial<CreateFoodDto>): Promise<Food> {
|
||||
|
||||
Reference in New Issue
Block a user