diff --git a/src/common/enums/message.enum.ts b/src/common/enums/message.enum.ts index 8fabe7e..f635400 100755 --- a/src/common/enums/message.enum.ts +++ b/src/common/enums/message.enum.ts @@ -719,6 +719,12 @@ export const enum CartMessage { WALLET_INSUFFICIENT = 'موجودی کیف پول کافی نیست', COUPON_MAX_USES_REACHED = 'حداکثر استفاده از کوپن به پایان رسیده است', ITEM_NOT_FOUND = 'آیتم در سبد خرید یافت نشد', + DELIVERY_METHOD_NOT_FOUND_FOR_RESTAURANT = 'روش ارسال برای این رستوران یافت نشد', + COUPON_CANNOT_BE_APPLIED = 'این کوپن قابل اعمال بر روی آیتم‌های سبد خرید شما نیست. لطفا آیتم‌هایی از دسته‌بندی‌ها یا غذاهای مشخص شده اضافه کنید', + FOODS_MUST_HAVE_PICKUP_SERVE_FOR_COURIER = 'تمام غذاها باید قابلیت تحویل پیک داشته باشند. غذاهای زیر این قابلیت را ندارند: [foodTitles]', + FOOD_ONLY_AVAILABLE_DURING_MEAL_TIMES = 'غذا [foodTitle] فقط در ساعات وعده‌های غذایی (صبحانه، ناهار، عصرانه یا شام) در دسترس است. زمان فعلی خارج از ساعات وعده‌های غذایی است', + FOOD_ONLY_AVAILABLE_FOR_MEAL_TYPES = 'غذا [foodTitle] فقط برای [allowedMealTypes] در دسترس است. زمان فعلی [mealType] است که با این غذا سازگار نیست', + FOOD_ONLY_AVAILABLE_ON_DAYS = 'غذا [foodTitle] فقط در روزهای [allowedDays] در دسترس است. امروز [currentDay] است که این غذا در دسترس نیست', } export const enum PaymentMessage { diff --git a/src/modules/cart/providers/cart-validation.service.ts b/src/modules/cart/providers/cart-validation.service.ts index cf79146..7d3aa69 100644 --- a/src/modules/cart/providers/cart-validation.service.ts +++ b/src/modules/cart/providers/cart-validation.service.ts @@ -17,7 +17,7 @@ import { CartMessage } from 'src/common/enums/message.enum'; @Injectable() export class CartValidationService { - constructor(private readonly em: EntityManager) {} + constructor(private readonly em: EntityManager) { } /** * Validate food exists, belongs to restaurant, has inventory, and check stock @@ -112,7 +112,7 @@ export class CartValidationService { longitude?: number | null, ): Promise { if (latitude === undefined || latitude === null || longitude === undefined || longitude === null) { - throw new BadRequestException('Address does not have coordinates'); + throw new BadRequestException(CartMessage.ADDRESS_NO_COORDINATES); } const restaurant = await this.getRestaurantOrFail(restaurantId); @@ -151,9 +151,7 @@ export class CartValidationService { }); if (!deliveryMethod) { - throw new NotFoundException( - `Delivery method with ID ${deliveryMethodId} not found for restaurant ${restaurantId}`, - ); + throw new NotFoundException(CartMessage.DELIVERY_METHOD_NOT_FOUND_FOR_RESTAURANT); } return deliveryMethod; @@ -275,9 +273,7 @@ export class CartValidationService { if (matchesCategory || matchesFood) return; } - throw new BadRequestException( - 'This coupon cannot be applied to the items in your cart. Please add items from the specified categories or foods.', - ); + throw new BadRequestException(CartMessage.COUPON_CANNOT_BE_APPLIED); } /** @@ -311,7 +307,7 @@ export class CartValidationService { if (foodsWithoutPickupServe.length > 0) { const foodTitles = foodsWithoutPickupServe.map(f => f.title || f.id).join(', '); throw new BadRequestException( - `All foods must have pickupServe enabled for courier delivery. The following foods do not: ${foodTitles}`, + CartMessage.FOODS_MUST_HAVE_PICKUP_SERVE_FOR_COURIER.replace('[foodTitles]', foodTitles), ); } } @@ -376,16 +372,27 @@ export class CartValidationService { // If current time is outside meal hours, throw error if (mealType === null) { + const foodTitle = food.title || food.id; throw new BadRequestException( - `Food ${food.title || food.id} is only available during meal times (breakfast, lunch, snack, or dinner). Current time is outside meal hours.`, + CartMessage.FOOD_ONLY_AVAILABLE_DURING_MEAL_TIMES.replace('[foodTitle]', foodTitle), ); } // Check if current meal type is in food's allowed meal types if (!food.mealTypes.includes(mealType)) { - const allowedMealTypes = food.mealTypes.join(', '); + const foodTitle = food.title || food.id; + const mealTypeMap: Record = { + [MealType.BREAKFAST]: 'صبحانه', + [MealType.LUNCH]: 'ناهار', + [MealType.SNACK]: 'عصرانه', + [MealType.DINNER]: 'شام', + }; + const allowedMealTypes = food.mealTypes.map(mt => mealTypeMap[mt]).join(', '); + const currentMealType = mealType ? mealTypeMap[mealType] : mealType; throw new BadRequestException( - `Food ${food.title || food.id} is only available for ${allowedMealTypes}. Current meal time is ${mealType}, which is incompatible.`, + CartMessage.FOOD_ONLY_AVAILABLE_FOR_MEAL_TYPES.replace('[foodTitle]', foodTitle) + .replace('[allowedMealTypes]', allowedMealTypes) + .replace('[mealType]', currentMealType), ); } } @@ -403,11 +410,14 @@ export class CartValidationService { // Check if current weekday is in food's allowed weekdays if (!food.weekDays.includes(iranWeekDay)) { - const dayNames = ['Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']; + const dayNames = ['شنبه', 'یکشنبه', 'دوشنبه', 'سه‌شنبه', 'چهارشنبه', 'پنج‌شنبه', 'جمعه']; const currentDayName = dayNames[iranWeekDay]; const allowedDays = food.weekDays.map(day => dayNames[day]).join(', '); + const foodTitle = food.title || food.id; throw new BadRequestException( - `Food ${food.title || food.id} is only available on ${allowedDays}. Today is ${currentDayName}, which is not available.`, + CartMessage.FOOD_ONLY_AVAILABLE_ON_DAYS.replace('[foodTitle]', foodTitle) + .replace('[allowedDays]', allowedDays) + .replace('[currentDay]', currentDayName), ); } } diff --git a/src/seeders/foods.seeder.ts b/src/seeders/foods.seeder.ts index 2b01d12..c84e3b6 100644 --- a/src/seeders/foods.seeder.ts +++ b/src/seeders/foods.seeder.ts @@ -35,8 +35,8 @@ export class FoodsSeeder { mealTypes: foodData.mealTypes ?? [], discount: foodData.discount ?? 0, score: foodData.score ?? 0, - inPlaceServe: foodData.inPlaceServe ?? false, - pickupServe: foodData.pickupServe ?? false, + inPlaceServe: true, + pickupServe: true, images: foodData.images, isSpecialOffer: foodData.isSpecialOffer ?? false, });