This commit is contained in:
2026-01-07 12:13:45 +03:30
parent 27ebf4a7b6
commit f2284c103d
235 changed files with 180468 additions and 1 deletions
+117
View File
@@ -0,0 +1,117 @@
import type { EntityManager } from '@mikro-orm/core';
import { Seeder } from '@mikro-orm/seeder';
import { Restaurant } from '../modules/restaurants/entities/restaurant.entity';
import { PermissionsSeeder } from './permissions.seeder';
import { RolesSeeder } from './roles.seeder';
import { RestaurantsSeeder } from './restaurants.seeder';
import { PaymentMethodsSeeder } from './payment-methods.seeder';
import { DeliveryMethodsSeeder } from './delivery-methods.seeder';
import { SchedulesSeeder } from './schedules.seeder';
import { CategoriesSeeder } from './categories.seeder';
import { FoodsSeeder } from './foods.seeder';
import { AdminsSeeder } from './admins.seeder';
import { UsersSeeder } from './users.seeder';
import { CouponsSeeder } from './coupons.seeder';
import { NotificationPreferencesSeeder } from './notification-preferences.seeder';
import { UserWalletsSeeder } from './user-wallets.seeder';
import { InventorySeeder } from './inventory.seeder';
// import { NotificationsSeeder } from './notifications.seeder';
export class DatabaseSeeder extends Seeder {
async run(em: EntityManager) {
const TOTAL_STEPS = 15;
console.info('[Seeder] Starting database seed');
// 1. Create Permissions
console.info(`[Seeder] Step 1/${TOTAL_STEPS}: Creating permissions`);
const permissionsSeeder = new PermissionsSeeder();
const permissions = await permissionsSeeder.run(em);
console.info(`[Seeder] Step 1/${TOTAL_STEPS}: Done`);
// 2. Create Roles
console.info(`[Seeder] Step 2/${TOTAL_STEPS}: Creating roles`);
const rolesSeeder = new RolesSeeder();
const rolesMap = await rolesSeeder.run(em, permissions);
console.info(`[Seeder] Step 2/${TOTAL_STEPS}: Done`);
// 3. Create Restaurants
console.info(`[Seeder] Step 3/${TOTAL_STEPS}: Creating restaurants`);
const restaurantsSeeder = new RestaurantsSeeder();
const restaurantsMap = await restaurantsSeeder.run(em);
console.info(`[Seeder] Step 3/${TOTAL_STEPS}: Done`);
// 4. Create Payment Methods for all Restaurants
console.info(`[Seeder] Step 4/${TOTAL_STEPS}: Creating payment methods`);
const allRestaurants = await em.find(Restaurant, {});
const paymentMethodsSeeder = new PaymentMethodsSeeder();
await paymentMethodsSeeder.run(em, allRestaurants);
console.info(`[Seeder] Step 4/${TOTAL_STEPS}: Done`);
// 5. Create Delivery Methods for all Restaurants
console.info(`[Seeder] Step 5/${TOTAL_STEPS}: Creating delivery methods`);
const deliveryMethodsSeeder = new DeliveryMethodsSeeder();
await deliveryMethodsSeeder.run(em, allRestaurants);
console.info(`[Seeder] Step 5/${TOTAL_STEPS}: Done`);
// 6. Create Schedules for all Restaurants
console.info(`[Seeder] Step 6/${TOTAL_STEPS}: Creating schedules`);
const schedulesSeeder = new SchedulesSeeder();
await schedulesSeeder.run(em, allRestaurants);
console.info(`[Seeder] Step 6/${TOTAL_STEPS}: Done`);
// 7. Create Notification Preferences for all Restaurants
console.info(`[Seeder] Step 7/${TOTAL_STEPS}: Creating notification preferences`);
const notificationPreferencesSeeder = new NotificationPreferencesSeeder();
await notificationPreferencesSeeder.run(em, allRestaurants);
console.info(`[Seeder] Step 7/${TOTAL_STEPS}: Done`);
// 8. Create Categories
console.info(`[Seeder] Step 8/${TOTAL_STEPS}: Creating categories`);
const categoriesSeeder = new CategoriesSeeder();
const categoriesMap = await categoriesSeeder.run(em, restaurantsMap);
console.info(`[Seeder] Step 8/${TOTAL_STEPS}: Done`);
// 9. Create Foods
console.info(`[Seeder] Step 9/${TOTAL_STEPS}: Creating foods`);
const foodsSeeder = new FoodsSeeder();
await foodsSeeder.run(em, restaurantsMap, categoriesMap);
console.info(`[Seeder] Step 9/${TOTAL_STEPS}: Done`);
// 10. Create Inventory for all Foods
console.info(`[Seeder] Step 10/${TOTAL_STEPS}: Creating inventory`);
const inventorySeeder = new InventorySeeder();
await inventorySeeder.run(em);
console.info(`[Seeder] Step 10/${TOTAL_STEPS}: Done`);
// 11. Create Coupons
console.info(`[Seeder] Step 11/${TOTAL_STEPS}: Creating coupons`);
const couponsSeeder = new CouponsSeeder();
await couponsSeeder.run(em, restaurantsMap);
console.info(`[Seeder] Step 11/${TOTAL_STEPS}: Done`);
// 12. Create Admins
console.info(`[Seeder] Step 12/${TOTAL_STEPS}: Creating admins`);
const adminsSeeder = new AdminsSeeder();
await adminsSeeder.run(em, rolesMap, restaurantsMap);
console.info(`[Seeder] Step 12/${TOTAL_STEPS}: Done`);
// 13. Create Users
console.info(`[Seeder] Step 13/${TOTAL_STEPS}: Creating users`);
const usersSeeder = new UsersSeeder();
await usersSeeder.run(em);
console.info(`[Seeder] Step 13/${TOTAL_STEPS}: Done`);
// 14. Create User Wallets
console.info(`[Seeder] Step 14/${TOTAL_STEPS}: Creating user wallets`);
const userWalletsSeeder = new UserWalletsSeeder();
await userWalletsSeeder.run(em);
console.info(`[Seeder] Step 14/${TOTAL_STEPS}: Done`);
// 15. Create Notifications for admins and users for all restaurants
console.info(`[Seeder] Step 15/${TOTAL_STEPS}: (optional) creating notifications`);
// const notificationsSeeder = new NotificationsSeeder();
// await notificationsSeeder.run(em);
console.info(`[Seeder] Step 15/${TOTAL_STEPS}: Done`);
console.info('[Seeder] Database seed completed');
}
}
+42
View File
@@ -0,0 +1,42 @@
import type { EntityManager } from '@mikro-orm/core';
import { Admin } from '../modules/admin/entities/admin.entity';
import { AdminRole } from '../modules/admin/entities/adminRole.entity';
import type { Role } from '../modules/roles/entities/role.entity';
import type { Restaurant } from '../modules/restaurants/entities/restaurant.entity';
import { adminsData } from './data/admins.data';
import { normalizePhone } from '../modules/utils/phone.util';
export class AdminsSeeder {
async run(em: EntityManager, rolesMap: Map<string, Role>, restaurantsMap: Map<string, Restaurant>): Promise<void> {
for (const adminData of adminsData) {
const existingAdmin = await em.findOne(Admin, { phone: adminData.phone });
if (existingAdmin) continue;
const role = rolesMap.get(adminData.roleName);
if (!role) continue;
const restaurant = adminData.restaurantSlug ? restaurantsMap.get(adminData.restaurantSlug) : null;
// For restaurant role, restaurant is required
if (!restaurant) continue;
const admin = em.create(Admin, {
phone: normalizePhone(adminData.phone),
firstName: adminData.firstName,
lastName: adminData.lastName,
});
em.persist(admin);
// Create AdminRole linking admin to role and restaurant
const adminRole = em.create(AdminRole, {
admin,
role,
restaurant: adminData.restaurantSlug ? restaurant : null,
});
em.persist(adminRole);
admin.roles.add(adminRole);
}
await em.flush();
}
}
+395
View File
@@ -0,0 +1,395 @@
import type { EntityManager } from '@mikro-orm/core';
import { Category } from '../modules/foods/entities/category.entity';
import type { Restaurant } from '../modules/restaurants/entities/restaurant.entity';
import { categoriesData } from './data/categories.data';
import * as fs from 'fs';
import * as path from 'path';
interface IconData {
index: number;
name: string;
url: string;
}
export class CategoriesSeeder {
private icons: IconData[] = [];
private iconIndex = 0;
private loadIcons(): void {
if (this.icons.length > 0) return;
const iconsPath = path.join(process.cwd(), 'dump', 'named_icons.csv');
const csvContent = fs.readFileSync(iconsPath, 'utf-8');
const lines = csvContent.split('\n').slice(1); // Skip header
this.icons = lines
.filter(line => line.trim())
.map(line => {
const parts = line.split(',');
return {
index: parseInt(parts[0].replace(/"/g, '')),
name: parts[1].replace(/"/g, ''),
url: parts[2].replace(/"/g, '')
};
});
}
private getIconForCategory(categoryTitle: string): string | undefined {
this.loadIcons();
if (this.icons.length === 0) return undefined;
// Create a mapping of keywords to icon names
const iconMapping: Record<string, string[]> = {
// Pizza
'پیتزا': ['pizza'],
// Pasta
'پاستا': ['fast-food'],
// Steak
'استیک': ['meat', 'meat 2'],
// Burger
'برگر': ['hanburger'],
// Salad
'سالاد': ['broccoli'],
// Appetizer/Appetizers
'پیش غذا': ['chicken', 'fast-food'],
// Main Course
'غذای اصلی': ['hanburger', 'meat'],
'خوراک': ['hanburger', 'meat'],
'ناهار': ['hanburger', 'meat'],
// Sandwich
'ساندویچ': ['bread'],
// Fried foods
'سوخاری': ['chicken', 'fast-food'],
// Cake/Dessert
'کیک': ['cookie1', 'cookie2'],
'دسر': ['cookie1', 'cookie2'],
// Ice Cream
'بستنی': ['ice cream', 'ice cream 3'],
'آیس': ['ice cream'],
// Breakfast
'صبحانه': ['bread', 'egg'],
// Drinks - general
'نوشیدنی': ['drink', 'drink2', 'bottle1', 'bottle2'],
// Coffee
'قهوه': ['drink', 'drink2'],
'اسپرسو': ['drink'],
'کافی': ['drink'],
// Tea
'چای': ['drink', 'drink2'],
'دمنوش': ['drink', 'drink2'],
// Cocktail/Mocktail
'ماکتل': ['wine glass', 'wine glass 2'],
'موهیتو': ['wine glass'],
// Shake/Smoothie
'شیک': ['ice cream'],
'اسموتی': ['ice cream'],
// Juice
'آبمیوه': ['juice', 'juice2', 'juice3'],
'ویتامینه': ['juice', 'juice2', 'juice3'],
// Hot Dog
'هات داگ': ['hot dog'],
// BBQ
'باربیکیو': ['barbecue', 'barbeque2'],
// BBQ Skewers
'کباب': ['skewer'],
// Soup
'آش': ['jar', 'dish'],
// Bread
'نان': ['bread'],
// Donut
'دونات': ['donuts'],
// Fish
'دریایی': ['fish'],
'ماهی': ['fish'],
// Chicken
'مرغ': ['chicken'],
// Egg
'تخم': ['egg', 'fried egg'],
// Vegetable
'سبزی': ['broccoli'],
// Fruit
'میوه': ['strawberry', 'cherry', 'grape', 'watermelon'],
// Milk
'شیر': ['bottle1'], // Note: there's no milk icon, using a generic one
// Cookie
'کوکی': ['cookie1', 'cookie2'],
// French Fries
'سیب زمینی': ['french fries'],
// Fast Food
'فست فود': ['fast-food'],
// Bakery
'نانوایی': ['bread'],
// Ice Tea
'آیس تی': ['drink', 'drink2'],
// Hot Pot
'حلیم': ['jar', 'dish'],
// Taco
'تاکو': ['taco'],
// Nachos
'ناچو': ['fast-food'],
// Sushi
'سوشی': ['fish'],
// Dumpling
'غالوش': ['basket'],
// Tempura
'تمپورا': ['fish'],
// Tofu
'توفو': ['jar'],
// Bibimbap
'بیبیمباب': ['fast-food'],
// Boba
'بوبا': ['drink', 'drink2'],
// Fish and Chips
'فیش اند چیپس': ['fish', 'french fries'],
// Focaccia
'فوکاچیا': ['bread'],
// Martini
'مارتینی': ['wine glass'],
// Mochi
'موچی': ['donuts'],
// Pancake
'پن کیک': ['bread'],
// Quesadilla
'کوئزادیا': ['quesadilla'],
// Origami
'اوريگامي': ['basket'],
// Pudding
'پودینگ': ['jar'],
// Sweet
'شیرین': ['candy'],
// Crossant
'کروسان': ['bread'],
// Bio
'بیو': ['broccoli'],
// Lemon
'لیمو': ['lemon'],
// Candy
'شیرینی': ['candy'],
// Lollipop
'آب نبات': ['lollipop'],
// Cherry
'گیلاس': ['cherry'],
// Strawberry
'توت فرنگی': ['strawberry'],
// Watermelon
'هندوانه': ['watermelon'],
// Avocado
'آووکادو': ['avocado'],
// Banana
'موز': ['banana'],
// Carrot
'هویج': ['carrot'],
// Cheese
'پنیر': ['cheese', 'cheese2'],
// Tomato
'گوجه': ['tomato'], // Note: no tomato icon
// Onion
'پیاز': ['onion'],
// Olive
'زیتون': ['olive'],
// Nuts
'آجیل': ['nuts'],
// Scales (for weighing)
'ترازو': ['scales'],
// Whisk
'همزن': ['whisk', 'whisk'],
// Mortar
'هاون': ['mortar'],
// Rolling pin
'والت': ['rolling pin'],
// Knife
'چاقو': ['knife'],
// Baby food
'کودک': ['baby bottle', 'baby bottle', 'baby pacifier'],
// Hat (chef hat)
'کلاه': ['hat robe', 'hat robe 2'],
// Candle (birthday)
'شمع': ['candle'],
// Fire
'آتش': ['fire'],
// Refrigerator
'یخچال': ['refrigerator'],
// Kitchen stove
'اجاق': ['kitchen stove'],
// Mixer
'میکسر': ['mixer'],
// Jar
'شیشه': ['jar'],
// Jelly
'ژله': ['jelly'],
// Soap
'صابون': ['soap'],
// Dish
'ظرف': ['dish'],
// Basket
'سبد': ['basket'],
// Salt
'نمک': ['solt'],
// Eggplant
'بادمجان': ['egg plant'],
// Wine
'شراب': ['wine glass', 'wine glass 2', 'wine glass 3'],
// Plate
'بشقاب': ['dish'],
// Fork and knife
'چنگال': ['spoon and fork 1', 'spoon and fork 2', 'spoon and knife', 'fork and knife'],
// Toast
'تست': ['toast']
};
// Find matching icon based on category title
for (const [keyword, iconNames] of Object.entries(iconMapping)) {
if (categoryTitle.includes(keyword)) {
// Find the first available icon from the list
for (const iconName of iconNames) {
const icon = this.icons.find(i => i.name.toLowerCase() === iconName.toLowerCase());
if (icon) {
return icon.url;
}
}
}
}
// Fallback: try to find any icon that might be related by partial name match
for (const icon of this.icons) {
const lowerTitle = categoryTitle.toLowerCase();
const lowerIconName = icon.name.toLowerCase();
// Check if any word in the category title matches part of the icon name
const titleWords = lowerTitle.split(/\s+/);
for (const word of titleWords) {
if (word.length > 2 && lowerIconName.includes(word)) {
return icon.url;
}
}
}
// Final fallback: return a random icon
const randomIndex = Math.floor(Math.random() * this.icons.length);
return this.icons[randomIndex]?.url;
}
async run(em: EntityManager, restaurantsMap: Map<string, Restaurant>): Promise<Map<string, Category>> {
const categoriesMap = new Map<string, Category>();
for (const catData of categoriesData) {
const restaurant = restaurantsMap.get(catData.restaurantSlug);
if (!restaurant) continue;
const existing = await em.findOne(Category, {
title: catData.title,
restaurant,
});
if (!existing) {
const avatarUrl = this.getIconForCategory(catData.title);
const category = em.create(Category, {
title: catData.title,
restaurant,
isActive: true,
avatarUrl,
});
em.persist(category);
categoriesMap.set(`${catData.restaurantSlug}-${catData.title}`, category);
} else {
categoriesMap.set(`${catData.restaurantSlug}-${catData.title}`, existing);
}
}
await em.flush();
return categoriesMap;
}
}
+42
View File
@@ -0,0 +1,42 @@
import type { EntityManager } from '@mikro-orm/core';
import { Coupon } from '../modules/coupons/entities/coupon.entity';
import type { Restaurant } from '../modules/restaurants/entities/restaurant.entity';
import { couponsData } from './data/coupons.data';
export class CouponsSeeder {
async run(em: EntityManager, restaurantsMap: Map<string, Restaurant>): Promise<void> {
for (const couponData of couponsData) {
const restaurant = restaurantsMap.get(couponData.restaurantSlug);
if (!restaurant) continue;
const existing = await em.findOne(Coupon, {
code: couponData.code,
restaurant: { id: restaurant.id },
});
if (!existing) {
const coupon = em.create(Coupon, {
restaurant,
code: couponData.code,
name: couponData.name,
description: couponData.description,
type: couponData.type,
value: couponData.value,
maxDiscount: couponData.maxDiscount,
minOrderAmount: couponData.minOrderAmount,
maxUses: couponData.maxUses,
maxUsesPerUser: couponData.maxUsesPerUser,
startDate: couponData.startDate ? new Date(couponData.startDate) : undefined,
endDate: couponData.endDate ? new Date(couponData.endDate) : undefined,
isActive: couponData.isActive,
usedCount: 0,
});
em.persist(coupon);
}
}
await em.flush();
}
}
+38
View File
@@ -0,0 +1,38 @@
export interface AdminData {
phone: string;
firstName: string;
lastName: string;
roleName: string;
restaurantSlug: string | null;
}
export const adminsData: AdminData[] = [
{
phone: '09362532122',
firstName: 'مرتضی',
lastName: 'مرتضایی',
roleName: 'مدیر ( پلن ویژه)',
restaurantSlug: 'boote',
},
{
phone: '09185290775',
firstName: 'حمید',
lastName: 'ضرقامی',
roleName: 'مدیر ( پلن ویژه)',
restaurantSlug: 'boote',
},
{
phone: '09129283395',
firstName: 'مهرداد',
lastName: 'مظفری',
roleName: 'مدیر ( پلن ویژه)',
restaurantSlug: 'boote',
},
{
phone: '09184317567',
firstName: 'ادمین',
lastName: 'هنر',
roleName: 'مدیر ( پلن ویژه)',
restaurantSlug: 'boote',
},
];
+430
View File
@@ -0,0 +1,430 @@
export interface CategoryData {
title: string;
restaurantSlug: string;
}
export const categoriesData: CategoryData[] = [ { title: 'پاستا', restaurantSlug: 'zhivan' },
{ title: 'پیتزا ایتالیایی', restaurantSlug: 'zhivan' },
{ title: 'پیتزا امریکایی', restaurantSlug: 'zhivan' },
{ title: 'استیک', restaurantSlug: 'zhivan' },
{ title: 'غذاهای گریل و فرنگی', restaurantSlug: 'zhivan' },
{ title: 'ساندویچ و برگر', restaurantSlug: 'zhivan' },
{ title: 'سوخاری', restaurantSlug: 'zhivan' },
{ title: 'سالاد', restaurantSlug: 'zhivan' },
{ title: 'پیش غذا', restaurantSlug: 'zhivan' },
{ title: 'نوشیدنی ها', restaurantSlug: 'zhivan' },
{ title: 'قهوه ', restaurantSlug: 'zhivan' },
{ title: 'موهیتو بار', restaurantSlug: 'zhivan' },
{ title: 'اسموتی و شیک ها ', restaurantSlug: 'zhivan' },
{ title: 'کیک و دسر', restaurantSlug: 'zhivan' },
{ title: 'چای و دمنوش ', restaurantSlug: 'zhivan' },
{ title: 'آیس کافی', restaurantSlug: 'zhivan' },
{ title: 'ایرانی', restaurantSlug: 'zhivan' },
{ title: 'شربت و عرقیجات', restaurantSlug: 'zhivan' },
{ title: 'ماکتیل', restaurantSlug: 'zhivan' },
{ title: 'نوشیدنی های گرم', restaurantSlug: 'sepanta' },
{ title: 'شیک ها', restaurantSlug: 'sepanta' },
{ title: 'کیک ها', restaurantSlug: 'sepanta' },
{ title: 'شربت ها ', restaurantSlug: 'sepanta' },
{ title: 'دمنوش ها', restaurantSlug: 'sepanta' },
{ title: 'صبحانه', restaurantSlug: 'ocafe' },
{ title: 'سیب زمینی ها', restaurantSlug: 'ocafe' },
{ title: 'پیش غذا و سالادها ', restaurantSlug: 'ocafe' },
{ title: 'غذاهای اصلی ', restaurantSlug: 'ocafe' },
{ title: 'کوکی و دسرها (آیتم ها به تعداد محدود در روز موجود می‌باشد )', restaurantSlug: 'ocafe' },
{ title: 'موکتل های ایرانی و ملل ', restaurantSlug: 'ocafe' },
{ title: 'شیک ها ', restaurantSlug: 'ocafe' },
{ title: 'نوشیدنی های گرم بر پایه اسپرسو ', restaurantSlug: 'ocafe' },
{ title: 'نوشیدنی های سرد بر پایه اسپرسو ', restaurantSlug: 'ocafe' },
{ title: 'نوشیدنی های گرم ملل ', restaurantSlug: 'ocafe' },
{ title: 'چای های ایرانی ', restaurantSlug: 'ocafe' },
{ title: 'دمنوش ها ', restaurantSlug: 'ocafe' },
{ title: 'قهوه های شنی ', restaurantSlug: 'ocafe' },
{ title: 'کلد برو ', restaurantSlug: 'ocafe' },
{ title: 'متدهای موج سوم', restaurantSlug: 'ocafe' },
{ title: 'آپشنال ', restaurantSlug: 'ocafe' },
{ title: 'نوشیدنی', restaurantSlug: 'ocafe' },
{ title: 'لقمه', restaurantSlug: 'ocafe' },
{ title: 'خوراک ها', restaurantSlug: 'easydizy' },
{ title: 'چاشنی ها', restaurantSlug: 'easydizy' },
{ title: 'نوشیدنی های خنک', restaurantSlug: 'easydizy' },
{ title: 'دسر ها', restaurantSlug: 'easydizy' },
{ title: 'پیش غذا ', restaurantSlug: 'boote' },
{ title: 'پیتزا آمریکایی', restaurantSlug: 'boote' },
{ title: 'پیتزا ایتالیایی ', restaurantSlug: 'boote' },
{ title: 'پاستا ', restaurantSlug: 'boote' },
{ title: 'ناهار بوته', restaurantSlug: 'boote' },
{ title: 'غذای اصلی', restaurantSlug: 'boote' },
{ title: 'ساندویچ', restaurantSlug: 'boote' },
{ title: 'اسپرسو بار', restaurantSlug: 'boote' },
{ title: 'دمی بار', restaurantSlug: 'boote' },
{ title: 'هاوس آف تی', restaurantSlug: 'boote' },
{ title: 'امریکن استایل', restaurantSlug: 'boote' },
{ title: 'کیک و دسر', restaurantSlug: 'boote' },
{ title: 'آیس کافی', restaurantSlug: 'boote' },
{ title: 'ماکتل بار', restaurantSlug: 'boote' },
{ title: 'ژلاتو میلک شیک', restaurantSlug: 'boote' },
{ title: 'صبحانه', restaurantSlug: 'boote' },
{ title: 'اسموتی بار', restaurantSlug: 'boote' },
{ title: 'چاکلت بار', restaurantSlug: 'boote' },
{ title: 'نوشیدنی های گرم ', restaurantSlug: 'life' },
{ title: 'نوشیدنی های سرد ', restaurantSlug: 'life' },
{ title: 'صبحانه ', restaurantSlug: 'life' },
{ title: 'میان وعده', restaurantSlug: 'life' },
{ title: 'بستنی', restaurantSlug: 'life' },
{ title: 'شیک', restaurantSlug: 'life' },
{ title: 'قلیان', restaurantSlug: 'life' },
{ title: 'پیتزا ایتالیایی ', restaurantSlug: 'foodcourt' },
{ title: 'پیتزا آمریکایی ', restaurantSlug: 'foodcourt' },
{ title: 'پاستاها', restaurantSlug: 'foodcourt' },
{ title: 'استیک ها', restaurantSlug: 'foodcourt' },
{ title: 'برگرها', restaurantSlug: 'foodcourt' },
{ title: 'ایرانی', restaurantSlug: 'foodcourt' },
{ title: 'سالاد.', restaurantSlug: 'foodcourt' },
{ title: 'پیش غذا.', restaurantSlug: 'foodcourt' },
{ title: 'نوشیدنی ها ', restaurantSlug: 'foodcourt' },
{ title: 'کیک و دسر', restaurantSlug: 'foodcourt' },
{ title: 'اسپرسو بار', restaurantSlug: 'foodcourt' },
{ title: 'نوشیدنی های گرم', restaurantSlug: 'foodcourt' },
{ title: 'چای و دمنوش', restaurantSlug: 'foodcourt' },
{ title: 'آیس کافه', restaurantSlug: 'foodcourt' },
{ title: 'میلک شیک', restaurantSlug: 'foodcourt' },
{ title: 'نوشیدی های سرد', restaurantSlug: 'foodcourt' },
{ title: 'قهوه های دمی.', restaurantSlug: 'foodcourt' },
{ title: 'گلاسه ها', restaurantSlug: 'foodcourt' },
{ title: 'صبحانه ', restaurantSlug: 'foodcourt' },
{ title: ' پیش غذا', restaurantSlug: 'banicho' },
{ title: 'کباب ها ', restaurantSlug: 'banicho' },
{ title: 'دمنوش', restaurantSlug: 'banicho' },
{ title: 'قهوه های دمی', restaurantSlug: 'banicho' },
{ title: 'جگر گوسفندی', restaurantSlug: 'banicho' },
{ title: 'جگر گوساله', restaurantSlug: 'banicho' },
{ title: 'بارسرد ', restaurantSlug: 'banicho' },
{ title: 'بارگرم', restaurantSlug: 'banicho' },
{ title: 'نوشیدنی گرم بر پایه اسپرسو', restaurantSlug: 'blacksugar' },
{ title: ' نوشیدنی گرم ', restaurantSlug: 'blacksugar' },
{ title: 'قهوه سرد', restaurantSlug: 'blacksugar' },
{ title: ' قهوه دمی', restaurantSlug: 'blacksugar' },
{ title: ' میان وعده و دسر', restaurantSlug: 'blacksugar' },
{ title: 'پیش غذاها', restaurantSlug: 'Piano' },
{ title: 'ساندویچ و برگر', restaurantSlug: 'Piano' },
{ title: 'پیتزا امریکایی', restaurantSlug: 'Piano' },
{ title: 'پیتزا ایتالیایی', restaurantSlug: 'Piano' },
{ title: 'پاستا', restaurantSlug: 'Piano' },
{ title: 'استیک', restaurantSlug: 'Piano' },
{ title: 'سوخاری', restaurantSlug: 'Piano' },
{ title: 'سالاد', restaurantSlug: 'Piano' },
{ title: 'بشقاب', restaurantSlug: 'Piano' },
{ title: 'پیده', restaurantSlug: 'Piano' },
{ title: 'خوراک', restaurantSlug: 'Piano' },
{ title: 'نوشیدنی گرم', restaurantSlug: 'Piano' },
{ title: 'نوشیدنی سرد', restaurantSlug: 'Piano' },
{ title: 'دسر و کیک', restaurantSlug: 'Piano' },
{ title: 'بستنی', restaurantSlug: 'Piano' },
{ title: 'دمنوش گیاهی', restaurantSlug: 'Piano' },
{ title: 'اسموتی', restaurantSlug: 'Piano' },
{ title: 'شیک', restaurantSlug: 'Piano' },
{ title: 'ماکتل ها', restaurantSlug: 'Piano' },
{ title: 'شربت ها', restaurantSlug: 'Piano' },
{ title: 'غذا', restaurantSlug: 'saadat' },
{ title: 'فرنگی', restaurantSlug: 'saadat' },
{ title: 'سالاد ها', restaurantSlug: 'saadat' },
{ title: 'نوشیدنی', restaurantSlug: 'saadat' },
{ title: 'قلیان', restaurantSlug: 'saadat' },
{ title: 'نوشیدنی های گرم', restaurantSlug: 'saadat' },
{ title: 'آیس کافی', restaurantSlug: 'saadat' },
{ title: 'چای', restaurantSlug: 'saadat' },
{ title: 'قهوه نسل ۳', restaurantSlug: 'saadat' },
{ title: 'ماکتل ها', restaurantSlug: 'saadat' },
{ title: 'شیک ها', restaurantSlug: 'saadat' },
{ title: 'پیش غذاها', restaurantSlug: 'saadat' },
{ title: 'خوراک مخصوص هفت خوان', restaurantSlug: 'Haaft khaan' },
{ title: 'خوراک', restaurantSlug: 'Haaft khaan' },
{ title: 'پیش غذا', restaurantSlug: 'Haaft khaan' },
{ title: 'نوشیدنی', restaurantSlug: 'Haaft khaan' },
{ title: 'چای و نوشیدنی گرم', restaurantSlug: 'Haaft khaan' },
{ title: 'قلیان', restaurantSlug: 'Haaft khaan' },
{ title: 'دسر', restaurantSlug: 'Haaft khaan' },
{ title: ' نوشیدنی های سرد', restaurantSlug: '1972Cafe' },
{ title: 'پیتزا ', restaurantSlug: '1972Cafe' },
{ title: 'قهوه و نوشیدنی گرم', restaurantSlug: '1972Cafe' },
{ title: 'پیش غذا و سالاد ', restaurantSlug: '1972Cafe' },
{ title: 'کیک', restaurantSlug: '1972Cafe' },
{ title: 'قهوه های دمی ', restaurantSlug: '1972Cafe' },
{ title: 'چای و دمنوش', restaurantSlug: '1972Cafe' },
{ title: 'پاستا', restaurantSlug: '1972Cafe' },
{ title: 'برگر', restaurantSlug: '1972Cafe' },
{ title: 'قلیان', restaurantSlug: '1972Cafe' },
{ title: 'پیتزاها', restaurantSlug: 'lounge1' },
{ title: 'پیتزا', restaurantSlug: 'Honar' },
{ title: 'برگر', restaurantSlug: 'cafe_sepanj' },
{ title: 'پاستا', restaurantSlug: 'cafe_sepanj' },
{ title: 'پنینی ', restaurantSlug: 'cafe_sepanj' },
{ title: 'هات داگ ', restaurantSlug: 'cafe_sepanj' },
{ title: 'سوخاری', restaurantSlug: 'cafe_sepanj' },
{ title: 'سیب زمینی', restaurantSlug: 'cafe_sepanj' },
{ title: 'سالاد', restaurantSlug: 'cafe_sepanj' },
{ title: 'نوشیدنی', restaurantSlug: 'cafe_sepanj' },
{ title: 'اسپرسو بار', restaurantSlug: 'cafe_sepanj' },
{ title: 'نوشیدنی گرم', restaurantSlug: 'cafe_sepanj' },
{ title: 'دمی', restaurantSlug: 'cafe_sepanj' },
{ title: ' ایس کافی', restaurantSlug: 'cafe_sepanj' },
{ title: 'چای دمنوش', restaurantSlug: 'cafe_sepanj' },
{ title: 'کیک', restaurantSlug: 'cafe_sepanj' },
{ title: 'شیک', restaurantSlug: 'cafe_sepanj' },
{ title: 'نوشیدنی سرد', restaurantSlug: 'cafe_sepanj' },
{ title: 'سیروپ', restaurantSlug: 'monikh' },
{ title: 'کیک', restaurantSlug: 'monikh' },
{ title: 'ساندویچ سرد', restaurantSlug: 'monikh' },
{ title: 'بر پایه اسپرسو', restaurantSlug: 'monikh' },
{ title: 'ماچا', restaurantSlug: 'monikh' },
{ title: 'بدون اسپرسو', restaurantSlug: 'monikh' },
{ title: 'چای و دمنوش', restaurantSlug: 'monikh' },
{ title: 'شیک و اسموتی', restaurantSlug: 'monikh' },
{ title: 'نوشیدنی های گرم (بر پایه اسپرسو)', restaurantSlug: 'o-cafe' },
{ title: 'نوشیدنی های سرد ', restaurantSlug: 'o-cafe' },
{ title: ' نوشیدنی های گرم ملل', restaurantSlug: 'o-cafe' },
{ title: ' قهوه های شنی', restaurantSlug: 'o-cafe' },
{ title: ' شیک ها', restaurantSlug: 'o-cafe' },
{ title: ' کوکی ها و دسرها', restaurantSlug: 'o-cafe' },
{ title: ' کلد برو', restaurantSlug: 'o-cafe' },
{ title: ' موج سوم', restaurantSlug: 'o-cafe' },
{ title: ' چای های ایرانی', restaurantSlug: 'o-cafe' },
{ title: ' دمنوش ها', restaurantSlug: 'o-cafe' },
{ title: ' ماکتل ها', restaurantSlug: 'o-cafe' },
{ title: ' غذاهای اصلی', restaurantSlug: 'o-cafe' },
{ title: ' پیش غذاها', restaurantSlug: 'o-cafe' },
{ title: ' سیب زمینی ها', restaurantSlug: 'o-cafe' },
{ title: ' صبحانه ها', restaurantSlug: 'o-cafe' },
{ title: ' آپشنال', restaurantSlug: 'o-cafe' },
{ title: 'پیش غذا', restaurantSlug: 'yummyburger' },
{ title: 'برگرها', restaurantSlug: 'yummyburger' },
{ title: 'دبل برگرها', restaurantSlug: 'yummyburger' },
{ title: 'تریپل برگرها', restaurantSlug: 'yummyburger' },
{ title: 'پیتزا ها', restaurantSlug: 'yummyburger' },
{ title: 'نوشیدنی ها', restaurantSlug: 'yummyburger' },
{ title: 'ساندویچ', restaurantSlug: 'yummyburger' },
{ title: 'سالاد و پیش غذا', restaurantSlug: 'mahtabgarden' },
{ title: 'آش بار مهتاب', restaurantSlug: 'mahtabgarden' },
{ title: 'غذای اصلی', restaurantSlug: 'mahtabgarden' },
{ title: 'شربت بار مهتاب', restaurantSlug: 'mahtabgarden' },
{ title: 'برگر', restaurantSlug: 'mahtabgarden' },
{ title: 'کافی بار', restaurantSlug: 'mahtabgarden' },
{ title: 'نوشیدنی گرم شکلاتی', restaurantSlug: 'mahtabgarden' },
{ title: 'دسر و کیک', restaurantSlug: 'mahtabgarden' },
{ title: 'شیک', restaurantSlug: 'mahtabgarden' },
{ title: 'دمنوش بار', restaurantSlug: 'mahtabgarden' },
{ title: 'ماکتل بار', restaurantSlug: 'mahtabgarden' },
{ title: 'اسموتی', restaurantSlug: 'mahtabgarden' },
{ title: 'نوشیدنی سرد', restaurantSlug: 'mahtabgarden' },
{ title: 'نوشیدنی های بر پایه اسپرسو', restaurantSlug: 'dream' },
{ title: 'قهوه های دمی ', restaurantSlug: 'dream' },
{ title: 'نوشیدنی های گرم', restaurantSlug: 'dream' },
{ title: 'چای و دمنوش', restaurantSlug: 'dream' },
{ title: 'قهوه های سرد', restaurantSlug: 'dream' },
{ title: 'شیک ها', restaurantSlug: 'dream' },
{ title: 'موکتل و آب میوه ها', restaurantSlug: 'dream' },
{ title: 'شربت ها', restaurantSlug: 'dream' },
{ title: 'فانتزی', restaurantSlug: 'dream' },
{ title: 'افزودنی', restaurantSlug: 'dream' },
{ title: 'بستنی ', restaurantSlug: 'dream' },
{ title: 'دسر', restaurantSlug: 'dream' },
{ title: 'صبحانه', restaurantSlug: 'dream' },
{ title: 'پیتزا ایتالیایی', restaurantSlug: 'dream' },
{ title: 'برگر', restaurantSlug: 'dream' },
{ title: 'پیش غذا', restaurantSlug: 'dream' },
{ title: 'پاستا', restaurantSlug: 'dream' },
{ title: 'سوخاری', restaurantSlug: 'dream' },
{ title: 'خوراک', restaurantSlug: 'dream' },
{ title: 'پیده', restaurantSlug: 'dream' },
{ title: 'شیرینی', restaurantSlug: 'dream' },
{ title: 'استیک ها', restaurantSlug: 'dream' },
{ title: 'سالاد', restaurantSlug: 'dream' },
{ title: 'پیتزا آمریکایی', restaurantSlug: 'dream' },
{ title: 'غذای ایرانی', restaurantSlug: 'dream' },
{ title: 'باربیکیو', restaurantSlug: 'dream' },
{ title: 'پیش غذاها', restaurantSlug: 'lanka' },
{ title: 'ایران زمین', restaurantSlug: 'lanka' },
{ title: 'پیتزا ایتالیایی', restaurantSlug: 'lanka' },
{ title: 'برگرها', restaurantSlug: 'lanka' },
{ title: 'استیک ها', restaurantSlug: 'lanka' },
{ title: 'پاستا', restaurantSlug: 'lanka' },
{ title: 'سالاد', restaurantSlug: 'lanka' },
{ title: 'دریایی ها', restaurantSlug: 'lanka' },
{ title: 'شات سس ها', restaurantSlug: 'lanka' },
{ title: 'اسپرسو بار', restaurantSlug: 'lanka' },
{ title: 'نوشیدنی گرم', restaurantSlug: 'lanka' },
{ title: 'آیس کافی', restaurantSlug: 'lanka' },
{ title: 'میلک شیک', restaurantSlug: 'lanka' },
{ title: 'نوشیدنی سرد', restaurantSlug: 'lanka' },
{ title: 'کیک و دسر ', restaurantSlug: 'lanka' },
{ title: 'سوخاری ها', restaurantSlug: 'lanka' },
{ title: 'چای و دمنوش', restaurantSlug: 'lanka' },
{ title: 'قهوه دمی', restaurantSlug: 'lanka' },
{ title: 'اسموتی ', restaurantSlug: 'lanka' },
{ title: 'vip drink', restaurantSlug: 'lanka' },
{ title: 'اسپرسو', restaurantSlug: 'LIAN' },
{ title: 'اسپرسو با شیر', restaurantSlug: 'LIAN' },
{ title: 'بار گرم', restaurantSlug: 'LIAN' },
{ title: 'آیس کافی', restaurantSlug: 'LIAN' },
{ title: 'آیس', restaurantSlug: 'LIAN' },
{ title: 'ماکتیل', restaurantSlug: 'LIAN' },
{ title: 'شیک', restaurantSlug: 'LIAN' },
{ title: 'دمی', restaurantSlug: 'LIAN' },
{ title: 'اسموتی', restaurantSlug: 'LIAN' },
{ title: 'میان وعده', restaurantSlug: 'LIAN' },
{ title: 'کیک ها', restaurantSlug: 'LIAN' },
{ title: 'چای و دمنوش', restaurantSlug: 'LIAN' },
{ title: 'بار گرم', restaurantSlug: 'milco-pilco' },
{ title: 'چای ها', restaurantSlug: 'milco-pilco' },
{ title: 'دمنوش ها', restaurantSlug: 'milco-pilco' },
{ title: 'شیک ها', restaurantSlug: 'milco-pilco' },
{ title: 'بارسرد', restaurantSlug: 'milco-pilco' },
{ title: 'برگرها ', restaurantSlug: 'milco-pilco' },
{ title: 'هات داگ ها', restaurantSlug: 'milco-pilco' },
{ title: 'نوستالژی', restaurantSlug: 'milco-pilco' },
{ title: 'سوخاری', restaurantSlug: 'milco-pilco' },
{ title: 'سیب زمینی', restaurantSlug: 'milco-pilco' },
{ title: 'پاستا', restaurantSlug: 'milco-pilco' },
{ title: 'سالاد ', restaurantSlug: 'milco-pilco' },
{ title: 'اسپرسو بار', restaurantSlug: 'milco-pilco' },
{ title: 'نوشیدنی سرد بر پایه قهوه', restaurantSlug: 'milco-pilco' },
{ title: 'ساندویچ ', restaurantSlug: 'milco-pilco' },
{ title: 'نوشیدنی های گرم بر پایه قهوه', restaurantSlug: 'lama' },
{ title: 'نوشیدنی های گرم', restaurantSlug: 'lama' },
{ title: 'دمنوش ها', restaurantSlug: 'lama' },
{ title: 'نوشیدنی های سر بر پایه قهوه', restaurantSlug: 'lama' },
{ title: 'ماکتیل', restaurantSlug: 'lama' },
{ title: 'چای', restaurantSlug: 'lama' },
{ title: 'شیک', restaurantSlug: 'lama' },
{ title: 'پیتزا', restaurantSlug: 'lama' },
{ title: 'برگر', restaurantSlug: 'lama' },
{ title: 'ساندویچ', restaurantSlug: 'lama' },
{ title: 'ساندویچ نوستالژی', restaurantSlug: 'lama' },
{ title: 'سوخاری', restaurantSlug: 'lama' },
{ title: 'سیب زمینی', restaurantSlug: 'lama' },
{ title: 'پنه', restaurantSlug: 'lama' },
{ title: 'غذای ایرانی', restaurantSlug: 'kaj.foodhall' },
{ title: 'پیتزا آمریکایی', restaurantSlug: 'kaj.foodhall' },
{ title: 'پیتزا ایتالیایی', restaurantSlug: 'kaj.foodhall' },
{ title: 'برگر', restaurantSlug: 'kaj.foodhall' },
{ title: 'خوراک', restaurantSlug: 'kaj.foodhall' },
{ title: 'پیده', restaurantSlug: 'kaj.foodhall' },
{ title: 'سوخاری', restaurantSlug: 'kaj.foodhall' },
{ title: 'استیک', restaurantSlug: 'kaj.foodhall' },
{ title: 'پاستا', restaurantSlug: 'kaj.foodhall' },
{ title: 'پیش غذا', restaurantSlug: 'kaj.foodhall' },
{ title: 'سالاد', restaurantSlug: 'kaj.foodhall' },
{ title: 'نوشیدنی های بر پایه اسپرسو', restaurantSlug: 'kaj.foodhall' },
{ title: 'قهوه های دمی', restaurantSlug: 'kaj.foodhall' },
{ title: 'قهوه های سرد', restaurantSlug: 'kaj.foodhall' },
{ title: 'چای و دمنوش ', restaurantSlug: 'kaj.foodhall' },
{ title: 'نوشیدنی های گرم', restaurantSlug: 'kaj.foodhall' },
{ title: 'موکتل و آب میوه ها', restaurantSlug: 'kaj.foodhall' },
{ title: 'دسر', restaurantSlug: 'kaj.foodhall' },
{ title: 'شیک ', restaurantSlug: 'kaj.foodhall' },
{ title: 'بستنی', restaurantSlug: 'kaj.foodhall' },
{ title: 'شربت', restaurantSlug: 'kaj.foodhall' },
{ title: 'دسر', restaurantSlug: 'hamid' },
{ title: 'شیک', restaurantSlug: 'donat-factory' },
{ title: 'بستنی ویژه', restaurantSlug: 'donat-factory' },
{ title: 'دسر', restaurantSlug: 'donat-factory' },
{ title: 'اسموتی', restaurantSlug: 'donat-factory' },
{ title: 'آیس کافی', restaurantSlug: 'donat-factory' },
{ title: 'قهوه', restaurantSlug: 'donat-factory' },
{ title: 'نوشیدنی های گرم', restaurantSlug: 'donat-factory' },
{ title: 'دمنوش', restaurantSlug: 'donat-factory' },
{ title: 'آیس بستنی', restaurantSlug: 'donat-factory' },
{ title: 'ویتامینه', restaurantSlug: 'donat-factory' },
{ title: 'آبمیوه طبیعی', restaurantSlug: 'donat-factory' },
{ title: 'دونات اسپشیال ', restaurantSlug: 'donat-factory' },
{ title: 'دونات آرت', restaurantSlug: 'donat-factory' },
{ title: 'دونات فانتزی', restaurantSlug: 'donat-factory' },
{ title: 'دونات جنرال', restaurantSlug: 'donat-factory' },
{ title: 'رست نات', restaurantSlug: 'donat-factory' },
{ title: 'برلینر', restaurantSlug: 'donat-factory' },
{ title: 'دونات اسپال', restaurantSlug: 'donat-factory' },
{ title: 'دونات لقمه ای ', restaurantSlug: 'donat-factory' },
{ title: 'دونات لقمه ای', restaurantSlug: 'donat-factory' },
{ title: 'دونات ناتس', restaurantSlug: 'donat-factory' },
{ title: 'صبحانه', restaurantSlug: 'donat-factory' },
{ title: 'اسنک و‌ میان وعده', restaurantSlug: 'donat-factory' },
{ title: 'دونات دوبی ', restaurantSlug: 'donat-factory' },
{ title: 'منوی اقتصادی ', restaurantSlug: 'donat-factory' },
{ title: 'پیتزا آمریکایی', restaurantSlug: 'narsis' },
{ title: 'برگرها', restaurantSlug: 'narsis' },
{ title: 'پاستاها', restaurantSlug: 'narsis' },
{ title: 'پیش غذا', restaurantSlug: 'narsis' },
{ title: 'نوشیدنی سرد آماده', restaurantSlug: 'narsis' },
{ title: 'نوشیدنی گرم', restaurantSlug: 'narsis' },
{ title: 'قهوه', restaurantSlug: 'narsis' },
{ title: 'نوشیدنی های سرد', restaurantSlug: 'narsis' },
{ title: 'نوشیدنی های سرد بر پایه قهوه', restaurantSlug: 'narsis' },
{ title: 'نوشیدنی های طبیعی با بستنی', restaurantSlug: 'narsis' },
{ title: 'ﻧﻮﺷﯿﺪﻧﯽ ﻫﺎ ﺑﺮ ﭘﺎﯾﻪ ﺷﯿﺮ', restaurantSlug: 'narsis' },
{ title: 'شیک ﻫﺎ و آﯾﺲ پک ها', restaurantSlug: 'narsis' },
{ title: 'آﺑﻤﯿﻮه ﻫﺎی ﻃﺒﯿﻌﯽ', restaurantSlug: 'narsis' },
{ title: 'آﺑﻤﯿﻮه ﻫﺎی ترکیبی', restaurantSlug: 'narsis' },
{ title: 'افزودنی ها', restaurantSlug: 'narsis' },
{ title: 'کیک ها ', restaurantSlug: 'narsis' },
{ title: 'خوراک ها', restaurantSlug: 'narsis' },
{ title: 'غذاهای چلویی', restaurantSlug: 'narsis' },
{ title: 'قهوه گرم', restaurantSlug: 'Theory' },
{ title: 'قهوه سرد', restaurantSlug: 'Theory' },
{ title: 'قهوه دمی', restaurantSlug: 'Theory' },
{ title: 'ماکتل', restaurantSlug: 'Theory' },
{ title: 'اسموتی', restaurantSlug: 'Theory' },
{ title: 'نوشیدنی گرم', restaurantSlug: 'Theory' },
{ title: 'ساندویچ گرم', restaurantSlug: 'Theory' },
{ title: 'ساندویچ سرد', restaurantSlug: 'Theory' },
{ title: 'سالاد و پیش غذا', restaurantSlug: 'Theory' },
{ title: 'چای و دمنوش', restaurantSlug: 'Theory' },
{ title: 'دسر', restaurantSlug: 'Theory' },
{ title: 'صبحانه', restaurantSlug: 'Theory' },
{ title: 'شیک', restaurantSlug: 'Theory' },
{ title: 'اضافه بار', restaurantSlug: 'Theory' },
{ title: 'نوشیدنی گرم بر پایه اسپرسو', restaurantSlug: 'ahr_cofe' },
{ title: 'نوشیدنی گرم', restaurantSlug: 'ahr_cofe' },
{ title: 'نوشیدنی سرد بر پایه اسپرسو', restaurantSlug: 'ahr_cofe' },
{ title: 'دمنوش و چای', restaurantSlug: 'ahr_cofe' },
{ title: 'شیک', restaurantSlug: 'ahr_cofe' },
{ title: 'ماکتل', restaurantSlug: 'ahr_cofe' },
{ title: 'اسموتی', restaurantSlug: 'ahr_cofe' },
{ title: 'کیک و دسر', restaurantSlug: 'ahr_cofe' },
{ title: 'اسپرسو بار', restaurantSlug: 'cafe_meat' },
{ title: 'بارسرد بر پایه اسپرسو', restaurantSlug: 'cafe_meat' },
{ title: 'صبحانه', restaurantSlug: 'cafe_meat' },
{ title: 'پیش غذا', restaurantSlug: 'cafe_meat' },
{ title: 'دمنوش ها', restaurantSlug: 'cafe_meat' },
{ title: 'بارسرد', restaurantSlug: 'cafe_meat' },
{ title: 'شیک', restaurantSlug: 'cafe_meat' },
{ title: 'غذا اصلی', restaurantSlug: 'cafe_meat' },
{ title: 'بار گرم بدون کافئین ', restaurantSlug: 'cafe_meat' },
{ title: 'کیک', restaurantSlug: 'cafe_meat' },
{ title: 'قهوه ها', restaurantSlug: 'Moon' },
{ title: 'پیستری', restaurantSlug: 'Moon' },
{ title: 'چای و دمنوش', restaurantSlug: 'Moon' },
{ title: 'نوشیدنی سرد', restaurantSlug: 'Moon' },
{ title: 'ماکتل', restaurantSlug: 'Moon' },
{ title: 'بستنی', restaurantSlug: 'Moon' },
{ title: 'نوشیدنی گرم', restaurantSlug: 'Moon' },
{ title: 'ایتم های بر پایه شیر', restaurantSlug: 'Moon' },
{ title: 'بیکری', restaurantSlug: 'Moon' },
{ title: 'سانویچ سرد', restaurantSlug: 'Moon' },
{ title: 'سالاد', restaurantSlug: 'Moon' },
{ title: 'اب', restaurantSlug: 'Moon' },
{ title: 'پیتزا', restaurantSlug: 'Moon' },
{ title: 'پاستاها', restaurantSlug: 'passata' },
{ title: 'Menu star (Only for special days)', restaurantSlug: 'passata' },
{ title: 'تاپینگ بار', restaurantSlug: 'passata' },
{ title: 'چیاباتا(سندویچ‌)', restaurantSlug: 'passata' },
{ title: 'نوشیدنی', restaurantSlug: 'passata' },
{ title: 'آش ها', restaurantSlug: 'kolbe-setareh' },
{ title: 'غذاهای اصلی', restaurantSlug: 'kolbe-setareh' },
{ title: 'غذاهای ویژه در طول هفته', restaurantSlug: 'kolbe-setareh' },
{ title: 'صبحانه ', restaurantSlug: 'kolbe-setareh' },
{ title: 'نوشیدنی ها', restaurantSlug: 'kolbe-setareh' },
{ title: 'پیش غذا', restaurantSlug: 'kolbe-setareh' },
{ title: 'دسرها', restaurantSlug: 'kolbe-setareh' },
{ title: 'سرویس اضافه', restaurantSlug: 'kolbe-setareh' },
];
+94
View File
@@ -0,0 +1,94 @@
import { CouponType } from '../../modules/coupons/interface/coupon';
export interface CouponData {
restaurantSlug: string;
code: string;
name: string;
description?: string;
type: CouponType;
value: number;
maxDiscount?: number;
minOrderAmount?: number;
maxUses?: number;
maxUsesPerUser?: number;
startDate?: string;
endDate?: string;
isActive: boolean;
}
export const couponsData: CouponData[] = [
{
restaurantSlug: 'zhivan',
code: 'WELCOME10',
name: 'خوش آمدگویی ۱۰٪',
description: 'تخفیف ۱۰ درصدی برای اولین خرید',
type: CouponType.PERCENTAGE,
value: 10,
maxDiscount: 50000,
minOrderAmount: 100000,
maxUses: 100,
maxUsesPerUser: 1,
isActive: true,
},
{
restaurantSlug: 'zhivan',
code: 'FIXED50K',
name: 'تخفیف ۵۰ هزار تومانی',
description: 'تخفیف ثابت ۵۰ هزار تومانی',
type: CouponType.FIXED,
value: 50000,
minOrderAmount: 200000,
maxUses: 50,
maxUsesPerUser: 2,
isActive: true,
},
{
restaurantSlug: 'zhivan',
code: 'WEEKEND20',
name: 'تعطیلات ۲۰٪',
description: 'تخفیف ۲۰ درصدی برای آخر هفته',
type: CouponType.PERCENTAGE,
value: 20,
maxDiscount: 100000,
minOrderAmount: 150000,
maxUses: 200,
isActive: true,
},
{
restaurantSlug: 'boote',
code: 'FIRST15',
name: 'اولین خرید ۱۵٪',
description: 'تخفیف ۱۵ درصدی برای اولین خرید',
type: CouponType.PERCENTAGE,
value: 15,
maxDiscount: 75000,
minOrderAmount: 100000,
maxUses: 100,
maxUsesPerUser: 1,
isActive: true,
},
{
restaurantSlug: 'boote',
code: 'SAVE30K',
name: 'صرفه جویی ۳۰ هزار',
description: 'تخفیف ثابت ۳۰ هزار تومانی',
type: CouponType.FIXED,
value: 30000,
minOrderAmount: 100000,
maxUses: 100,
isActive: true,
},
{
restaurantSlug: 'boote',
code: 'VIP25',
name: 'ویژه ۲۵٪',
description: 'تخفیف ویژه ۲۵ درصدی',
type: CouponType.PERCENTAGE,
value: 25,
maxDiscount: 150000,
minOrderAmount: 200000,
maxUses: 50,
maxUsesPerUser: 1,
isActive: true,
},
];
+45
View File
@@ -0,0 +1,45 @@
import { DeliveryMethodEnum } from '../../modules/delivery/interface/delivery';
export interface DeliveryMethodData {
method: DeliveryMethodEnum;
description: string;
deliveryFee: number;
minOrderPrice: number;
enabled: boolean;
order: number;
}
export const deliveryMethodsData: DeliveryMethodData[] = [
{
method: DeliveryMethodEnum.DineIn,
description: 'سرو غذا در رستوران',
deliveryFee: 0,
minOrderPrice: 0,
enabled: true,
order: 1,
},
{
method: DeliveryMethodEnum.CustomerPickup,
description: 'برداشت غذا از رستوران',
deliveryFee: 0,
minOrderPrice: 0,
enabled: true,
order: 2,
},
{
method: DeliveryMethodEnum.DeliveryCar,
description: 'تحویل غذا در خودرو',
deliveryFee: 5000,
minOrderPrice: 50000,
enabled: true,
order: 3,
},
{
method: DeliveryMethodEnum.DeliveryCourier,
description: 'تحویل غذا با پیک',
deliveryFee: 10000,
minOrderPrice: 100000,
enabled: true,
order: 4,
},
];
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,29 @@
import { NotifChannelEnum, NotifTitleEnum } from '../../modules/notifications/interfaces/notification.interface';
export interface NotificationPreferenceData {
title: NotifTitleEnum;
channels: NotifChannelEnum[];
}
export const notificationPreferencesData: NotificationPreferenceData[] = [
{
title: NotifTitleEnum.PAGER_CREATED,
channels: [NotifChannelEnum.SMS, NotifChannelEnum.PUSH, NotifChannelEnum.IN_APP],
},
{
title: NotifTitleEnum.ORDER_CREATED,
channels: [NotifChannelEnum.SMS, NotifChannelEnum.PUSH, NotifChannelEnum.IN_APP],
},
{
title: NotifTitleEnum.PAYMENT_SUCCESS,
channels: [NotifChannelEnum.SMS, NotifChannelEnum.PUSH, NotifChannelEnum.IN_APP],
},
{
title: NotifTitleEnum.REVIEW_CREATED,
channels: [NotifChannelEnum.SMS, NotifChannelEnum.PUSH, NotifChannelEnum.IN_APP],
},
{
title: NotifTitleEnum.ORDER_STATUS_CHANGED,
channels: [NotifChannelEnum.SMS, NotifChannelEnum.PUSH, NotifChannelEnum.IN_APP],
},
];
+35
View File
@@ -0,0 +1,35 @@
import { PaymentMethodEnum, PaymentGatewayEnum } from '../../modules/payments/interface/payment';
export interface PaymentMethodData {
method: PaymentMethodEnum;
description: string;
enabled: boolean;
order: number;
gateway: PaymentGatewayEnum | null;
merchantId?: string;
}
export const paymentMethodsData: PaymentMethodData[] = [
{
method: PaymentMethodEnum.Online,
description: 'درگاه پرداخت زرین‌پال',
enabled: true,
order: 1,
gateway: PaymentGatewayEnum.ZarinPal,
merchantId: 'b6f55bd0-6eae-4045-aeb8-07d084fa8f73',
},
{
method: PaymentMethodEnum.Cash,
description: 'پرداخت نقدی',
enabled: true,
order: 2,
gateway: null,
},
{
method: PaymentMethodEnum.Wallet,
description: 'پرداخت از کیف پول',
enabled: true,
order: 3,
gateway: null,
},
];
+10
View File
@@ -0,0 +1,10 @@
import { Permission, PermissionTitles } from '../../common/enums/permission.enum';
export const getPermissionsData = () => {
return Object.values(Permission).map(name => ({
name,
title: PermissionTitles[name],
}));
};
+919
View File
@@ -0,0 +1,919 @@
import { PlanEnum } from 'src/modules/restaurants/interface/plan.interface';
export interface RestaurantData {
name: string;
slug: string;
domain: string;
isActive: boolean;
phone: string;
logo?: string;
score: {
purchaseAmount: string;
purchaseScore: string;
scoreAmount: string;
scoreCredit: string;
birthdayScore: string;
registerScore: string;
marriageDateScore: string;
referrerScore: string;
};
plan: PlanEnum;
subscriptionId: string;
}
export const restaurantsData: RestaurantData[] = [
{
name: 'ژیوان',
slug: 'zhivan',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/zhivan',
isActive: true,
phone: '',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1638870352717_61a3661f37a0d33354a6d210.png',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_zhivan_001',
},
{
name: 'سپنتا',
slug: 'sepanta',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/sepanta',
isActive: true,
phone: '',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1641199914860_61d2b72b2e8bd97126a70b5f.png',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_sepanta_001',
},
{
name: 'اکافه',
slug: 'ocafe',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/ocafe',
isActive: true,
phone: '',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1643274757715_61e509141601c7c7d9141989.png',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_ocafe_001',
},
{
name: 'رستوران ایزی دیزی',
slug: 'easydizy',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/easydizy',
isActive: true,
phone: '',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1644324825827_6202562b1ee4b0270db4ae58.png',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_easydizy_001',
},
{
name: 'کافه رستوران بوته',
slug: 'boote',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/boote',
isActive: true,
phone: '',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1644655737806_62076fa71ee4b0270db4c32d.png',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Premium,
subscriptionId: 'sub_seed_boote_001',
},
{
name: 'کافه لایف',
slug: 'life',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/life',
isActive: true,
phone: '',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1644838482386_6207b1211ee4b0270db4c4ae.png',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_life_001',
},
{
name: 'ninja park',
slug: 'foodcourt',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/foodcourt',
isActive: true,
phone: '',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1725286063770_6210b063adf126141b26173d.png',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_foodcourt_001',
},
{
name: 'هیزم',
slug: 'banicho',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/banicho',
isActive: true,
phone: '',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1699722686770_622dccbda03b80e0a44f1d3a.png',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_banicho_001',
},
{
name: 'بلک شوگر',
slug: 'blacksugar',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/blacksugar',
isActive: true,
phone: '',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1647809564910_62378f6bc1bb048b321cd949.png',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_blacksugar_001',
},
{
name: 'پیانو',
slug: 'Piano',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/Piano',
isActive: true,
phone: '',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1652476386948_627e3d972353df2fe6512c8f.png',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_Piano_001',
},
{
name: 'سعادت',
slug: 'saadat',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/saadat',
isActive: true,
phone: '',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1655296406771_62a9cff7128ed6fd013332dc.png',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_saadat_001',
},
{
name: 'هفت خوان',
slug: 'Haftkhan',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/Haftkhan',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_Haftkhan_001',
},
{
name: 'سفره خانه و باغ رستوران هفت خوان',
slug: 'Haaft khaan',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1657711159036_62cea8d47400250986c70a07.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/Haaft khaan',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_Haaft khaan_001',
},
{
name: '1972',
slug: '1972Cafe',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1658666648415_62dd3bf3faacb066e1206279.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/1972Cafe',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_1972Cafe_001',
},
{
name: 'لانژ',
slug: 'lounge1',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1659109491707_62e3ff5e96be484852cba3c3.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/lounge1',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_lounge1_001',
},
{
name: 'کافه رستوران هنر',
slug: 'Honar',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1662296508840_63131c3d96be484852d0a9ed.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/Honar',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_Honar_001',
},
{
name: 'خانه وانیلی',
slug: 'Vanilla',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1662977478952_631f0484e410c5322752c409.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/Vanilla',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_Vanilla_001',
},
{
name: '1972',
slug: '1972',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1672070842973_63a9c15f82d7fc8d726b8b2f.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/1972',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_1972_001',
},
{
name: 'نارسیس',
slug: 'Narcis',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/Narcis',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_Narcis_001',
},
{
name: 'کافه سپنج',
slug: 'cafe_sepanj',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1683113201780_6450aa9a98ff3c7414414230.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/cafe_sepanj',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_cafe_sepanj_001',
},
{
name: 'مونیخ',
slug: 'monikh',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1737820250944_6450d97a98ff3c7414414999.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/monikh',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_monikh_001',
},
{
name: 'اُ کافه',
slug: 'o-cafe',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1684406222541_6465ff4d98ff3c741442d56a.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/o-cafe',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_o-cafe_001',
},
{
name: 'یامی برگر',
slug: 'yummyburger',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1689594902563_64b3d17d98ff3c741448cccd.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/yummyburger',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_yummyburger_001',
},
{
name: 'کافه رستوران مهتاب',
slug: 'mahtabgarden',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1689965802684_64bad3b698ff3c741449521e.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/mahtabgarden',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_mahtabgarden_001',
},
{
name: 'dream',
slug: 'dream',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1692001432499_64d9e2b979f54f6403d7e0be.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/dream',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_dream_001',
},
{
name: 'لانکا',
slug: 'lanka',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1695032652234_650823be59383e8d7550ccb5.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/lanka',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_lanka_001',
},
{
name: '123',
slug: '123',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1696240982921_651a7ffe59383e8d7551eebf.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/123',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_123_001',
},
{
name: 'لیان',
slug: 'LIAN',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1701608905866_651ad03159383e8d7551f3be.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/LIAN',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_LIAN_001',
},
{
name: 'کافه رستوران لانکا',
slug: 'Lanka',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/Lanka',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_Lanka_001',
},
{
name: 'میلکو پلاس',
slug: 'milco-pilco',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1710166978715_65ef0b1d3ad722005756bb0f.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/milco-pilco',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_milco-pilco_001',
},
{
name: 'لاما',
slug: 'lama',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1710333176537_65ef1a093ad722005756bc8e.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/lama',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_lama_001',
},
{
name: 'کاج',
slug: 'kaj.foodhall',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1720963586174_6693d0cc136cc10070469510.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/kaj.foodhall',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_kaj.foodhall_001',
},
{
name: 'حمید',
slug: 'hamid',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1729929522774_671c9c58c3c0100063e4d1a9.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/hamid',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_hamid_001',
},
{
name: 'دونات فکتوری',
slug: 'donat-factory',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1731152090639_672f3c9bc3c0100063e6a526.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/donat-factory',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_donat-factory_001',
},
{
name: 'نارسیس',
slug: 'narsis',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1731314427492_6731c2b9c3c0100063e6e2ae.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/narsis',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_narsis_001',
},
{
name: 'تئوری',
slug: 'Theory',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1736665730887_677ab9f9a4463c0057e3ac5d.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/Theory',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_Theory_001',
},
{
name: 'testmenu',
slug: 'testmenu',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/testmenu',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_testmenu_001',
},
{
name: 'ahr_cafe',
slug: 'ahr_cofe',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1738074249830_6798e6aabd2ce20057144cfb.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/ahr_cofe',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_ahr_cofe_001',
},
{
name: 'cafe_meat',
slug: 'cafe_meat',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1739868881926_679b7fe7bd2ce200571498a8.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/cafe_meat',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_cafe_meat_001',
},
{
name: 'پیتزا خانواده',
slug: 'KFP',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1740470240551_67bd773f536282006220de43.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/KFP',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_KFP_001',
},
{
name: 'پیتزا خانواده ',
slug: 'KFP ',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/KFP ',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_KFP _001',
},
{
name: 'Themoon',
slug: 'Moon',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1743347876393_67e93f9e536282006224c40d.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/Moon',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_Moon_001',
},
{
name: 'زپارتی',
slug: 'zparty',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/zparty',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_zparty_001',
},
{
name: 'پاساتا پلاس',
slug: 'passata',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1749534426675_6847c5f3f114460057d617bf.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/passata',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_passata_001',
},
{
name: 'کلبه ستاره',
slug: 'kolbe-setareh',
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1751196871890_686100dd9086300011bdf7d0.png',
domain: 'https://dmenu-plus-front.dev.danakcorp.com/kolbe-setareh',
isActive: true,
phone: '',
score: {
purchaseAmount: '100000',
purchaseScore: '0',
scoreAmount: '0',
scoreCredit: '0',
birthdayScore: '0',
registerScore: '0',
marriageDateScore: '0',
referrerScore: '0',
},
plan: PlanEnum.Base,
subscriptionId: 'sub_seed_kolbe-setareh_001',
},
];
+37
View File
@@ -0,0 +1,37 @@
import { Permission } from '../../common/enums/permission.enum';
export interface RoleConfig {
name: string;
isSystem: boolean;
permissionFilter: (permissionName: Permission) => boolean;
}
export const rolesData: RoleConfig[] = [
{
name: 'مدیر (پلن پایه)',
isSystem: false,
permissionFilter: (name: Permission) =>
name === Permission.MANAGE_FOODS ||
name === Permission.MANAGE_CATEGORIES ||
name === Permission.MANAGE_SCHEDULES ||
name === Permission.MANAGE_PAGER ||
name === Permission.MANAGE_CONTACTS ||
name === Permission.MANAGE_ROLES ||
name === Permission.MANAGE_SETTINGS ||
name === Permission.MANAGE_ADMINS ||
name == Permission.VIEW_REPORTS ||
name == Permission.UPDATE_RESTAURANT
},
{
name: 'مدیر ( پلن ویژه)',
isSystem: false,
permissionFilter: () => true, // All permissions for restaurant role
},
{
name: 'حسابدار ',
isSystem: false,
permissionFilter: (name: Permission) =>
name === Permission.VIEW_REPORTS || name === Permission.MANAGE_PAYMENTS || name === Permission.MANAGE_ORDERS,
},
];
+10
View File
@@ -0,0 +1,10 @@
export interface TimeSlot {
openTime: string;
closeTime: string;
}
export const timeSlots: TimeSlot[] = [
{ openTime: '08:00', closeTime: '11:00' }, // Breakfast
{ openTime: '12:00', closeTime: '15:00' }, // Lunch
{ openTime: '18:00', closeTime: '23:00' }, // Dinner
];
+63
View File
@@ -0,0 +1,63 @@
export interface UserAddressData {
userPhone: string;
title: string;
address: string;
city: string;
province?: string;
postalCode?: string;
latitude: number;
longitude: number;
phone?: string;
isDefault: boolean;
}
export const userAddressesData: UserAddressData[] = [
{
userPhone: '09362532122',
title: 'خانه',
address: 'خیابان ولیعصر، پلاک 123',
city: 'تهران',
province: 'تهران',
postalCode: '1234567890',
latitude: 35.6892,
longitude: 51.389,
phone: '09362532122',
isDefault: true,
},
{
userPhone: '09185290775',
title: 'خانه',
address: 'خیابان انقلاب، پلاک 456',
city: 'تهران',
province: 'تهران',
postalCode: '1234567891',
latitude: 35.69,
longitude: 51.39,
phone: '09185290775',
isDefault: true,
},
{
userPhone: '09129283395',
title: 'خانه',
address: 'خیابان آزادی، پلاک 789',
city: 'تهران',
province: 'تهران',
postalCode: '1234567892',
latitude: 35.691,
longitude: 51.391,
phone: '09129283395',
isDefault: true,
},
{
userPhone: '09184317567',
title: 'خانه',
address: 'خیابان جمهوری، پلاک 321',
city: 'تهران',
province: 'تهران',
postalCode: '1234567893',
latitude: 35.692,
longitude: 51.392,
phone: '09184317567',
isDefault: true,
},
];
+63
View File
@@ -0,0 +1,63 @@
export interface UserData {
phone: string;
firstName: string;
lastName: string;
restaurantSlug: string;
birthDate: string;
marriageDate: string;
isActive: boolean;
gender: boolean;
wallet: number;
points: number;
}
export const usersData: UserData[] = [
{
phone: '09362532122',
firstName: 'مرتضی',
lastName: 'مرتضایی',
restaurantSlug: 'zhivan',
birthDate: '1990-01-01',
marriageDate: '2015-01-01',
isActive: true,
gender: true,
wallet: 250000,
points: 100,
},
{
phone: '09185290775',
firstName: 'حمید',
lastName: 'ضرغامی',
restaurantSlug: 'boote',
birthDate: '1992-01-01',
marriageDate: '2017-01-01',
isActive: true,
gender: true,
wallet: 250000,
points: 100,
},
{
phone: '09129283395',
firstName: 'مهرداد',
lastName: 'مظفری',
restaurantSlug: 'zhivan',
birthDate: '1988-01-01',
marriageDate: '2014-01-01',
isActive: true,
gender: true,
wallet: 250000,
points: 100,
},
{
phone: '09184317567',
firstName: 'مارال',
lastName: 'صادقی',
restaurantSlug: 'boote',
birthDate: '1995-01-01',
marriageDate: '2020-01-01',
isActive: true,
gender: false,
wallet: 250000,
points: 100,
},
];
+52
View File
@@ -0,0 +1,52 @@
import type { EntityManager } from '@mikro-orm/core';
import { Delivery } from '../modules/delivery/entities/delivery.entity';
import type { Restaurant } from '../modules/restaurants/entities/restaurant.entity';
import { deliveryMethodsData } from './data/delivery-methods.data';
import { DeliveryFeeTypeEnum } from 'src/modules/delivery/interface/delivery';
export class DeliveryMethodsSeeder {
async run(em: EntityManager, restaurants: Restaurant[]): Promise<void> {
for (const restaurant of restaurants) {
if (!restaurant) continue;
for (const methodData of deliveryMethodsData) {
const existing = await em.findOne(Delivery, {
restaurant: { id: restaurant.id },
method: methodData.method,
});
if (!existing) {
const delivery = em.create(Delivery, {
restaurant,
method: methodData.method,
description: methodData.description,
deliveryFee: methodData.deliveryFee,
minOrderPrice: methodData.minOrderPrice,
enabled: methodData.enabled,
order: methodData.order,
deliveryFeeType: DeliveryFeeTypeEnum.FIXED,
perKilometerFee: null,
distanceBasedMinCost: null,
});
em.persist(delivery);
} else {
// Update existing delivery method if needed
if (
existing.description !== methodData.description ||
existing.deliveryFee !== methodData.deliveryFee ||
existing.minOrderPrice !== methodData.minOrderPrice ||
existing.order !== methodData.order
) {
existing.description = methodData.description;
existing.deliveryFee = methodData.deliveryFee;
existing.minOrderPrice = methodData.minOrderPrice;
existing.order = methodData.order;
em.persist(existing);
}
}
}
}
await em.flush();
}
}
+73
View File
@@ -0,0 +1,73 @@
import type { EntityManager } from '@mikro-orm/core';
import { Food } from '../modules/foods/entities/food.entity';
import type { Restaurant } from '../modules/restaurants/entities/restaurant.entity';
import type { Category } from '../modules/foods/entities/category.entity';
import { MealType } from '../modules/foods/interface/food.interface';
import { foodsData } from './data/foods.data';
export class FoodsSeeder {
async run(
em: EntityManager,
restaurantsMap: Map<string, Restaurant>,
categoriesMap: Map<string, Category>,
): Promise<void> {
for (const foodData of foodsData) {
const restaurant = restaurantsMap.get(foodData.restaurantSlug);
const key = `${foodData.restaurantSlug}-${foodData.categoryTitle}`;
const normalize = (s: string) => (s || '').replace(/\s+/g, ' ').trim();
let category = categoriesMap.get(key);
// Fallback: try to find category by normalized title if exact key not found
if (!category) {
for (const [k, v] of categoriesMap.entries()) {
const parts = k.split('-');
const kSlug = parts[0];
const kTitle = parts.slice(1).join('-');
if (kSlug === foodData.restaurantSlug && normalize(kTitle) === normalize(foodData.categoryTitle)) {
category = v;
break;
}
}
}
if (!restaurant || !category) {
console.warn(
`Skipping food \"${foodData.title}\" — missing ${!restaurant ? 'restaurant' : 'category'} for key ${key}`,
);
continue;
}
const existing = await em.findOne(Food, {
title: foodData.title,
restaurant,
});
if (!existing) {
const food = em.create(Food, {
title: foodData.title,
desc: foodData.desc,
content: foodData.content,
price: foodData.price,
restaurant,
category,
isActive: foodData.isActive,
// new fields on Food entity
weekDays: foodData.weekDays ?? [0, 1, 2, 3, 4, 5, 6],
mealTypes: foodData.mealTypes ?? [MealType.BREAKFAST, MealType.LUNCH, MealType.DINNER, MealType.SNACK],
discount: foodData.discount ?? 0,
score: foodData.score ?? 0,
inPlaceServe: true,
pickupServe: true,
images: foodData.images,
isSpecialOffer: foodData.isSpecialOffer ?? false,
});
em.persist(food);
}
}
await em.flush();
}
}
+4
View File
@@ -0,0 +1,4 @@
import { DatabaseSeeder } from './DatabaseSeeder';
export { DatabaseSeeder };
export default DatabaseSeeder;
+29
View File
@@ -0,0 +1,29 @@
import type { EntityManager } from '@mikro-orm/core';
import { Food } from '../modules/foods/entities/food.entity';
import { Inventory } from '../modules/inventory/entities/inventory.entity';
export class InventorySeeder {
async run(em: EntityManager): Promise<void> {
const foods = await em.find(Food, {});
for (const food of foods) {
// Check if inventory already exists for this food
const existingInventory = await em.findOne(Inventory, {
food: { id: food.id },
});
if (!existingInventory) {
const inventory = em.create(Inventory, {
food,
totalStock: 50,
availableStock: 50,
});
em.persist(inventory);
}
}
await em.flush();
}
}
@@ -0,0 +1,36 @@
import type { EntityManager } from '@mikro-orm/core';
import { NotificationPreference } from '../modules/notifications/entities/notification-preference.entity';
import type { Restaurant } from '../modules/restaurants/entities/restaurant.entity';
import { notificationPreferencesData } from './data/notification-preferences.data';
export class NotificationPreferencesSeeder {
async run(em: EntityManager, restaurants: Restaurant[]): Promise<void> {
for (const restaurant of restaurants) {
if (!restaurant) continue;
for (const preferenceData of notificationPreferencesData) {
const existing = await em.findOne(NotificationPreference, {
restaurant: { id: restaurant.id },
title: preferenceData.title,
});
if (!existing) {
const preference = em.create(NotificationPreference, {
restaurant,
title: preferenceData.title,
channels: preferenceData.channels,
});
em.persist(preference);
} else {
// Update existing preference if notification type changed
if (existing.channels.length !== preferenceData.channels.length) {
existing.channels = preferenceData.channels;
em.persist(existing);
}
}
}
}
await em.flush();
}
}
+68
View File
@@ -0,0 +1,68 @@
import type { EntityManager } from '@mikro-orm/core';
import { Notification } from '../modules/notifications/entities/notification.entity';
import { Admin } from '../modules/admin/entities/admin.entity';
import { User } from '../modules/users/entities/user.entity';
import { Restaurant } from '../modules/restaurants/entities/restaurant.entity';
import { NotifTitleEnum } from '../modules/notifications/interfaces/notification.interface';
export class NotificationsSeeder {
/**
* Seeds notifications for all admins and users for every restaurant.
* Ensures up to 33 notifications exist per (restaurant, admin) and (restaurant, user).
*/
async run(em: EntityManager): Promise<void> {
const restaurants = await em.find(Restaurant, {});
const admins = await em.find(Admin, {});
const users = await em.find(User, {});
const titles = Object.values(NotifTitleEnum);
for (const restaurant of restaurants) {
if (!restaurant) continue;
// Admin notifications
for (const admin of admins) {
if (!admin) continue;
const existingCount = await em.count(Notification, {
restaurant: { id: restaurant.id },
admin: { id: admin.id },
});
const toCreate = Math.max(0, 33 - (existingCount || 0));
for (let i = 0; i < toCreate; i++) {
const notif = em.create(Notification, {
restaurant,
admin,
title: titles[i % titles.length] as NotifTitleEnum,
content: `Seeded notification ${i + 1} for admin ${admin.id} at ${restaurant.slug}`,
});
em.persist(notif);
}
}
// User notifications
for (const user of users) {
if (!user) continue;
const existingCount = await em.count(Notification, {
restaurant: { id: restaurant.id },
user: { id: user.id },
});
const toCreate = Math.max(0, 33 - (existingCount || 0));
for (let i = 0; i < toCreate; i++) {
const notif = em.create(Notification, {
restaurant,
user,
title: titles[i % titles.length] as NotifTitleEnum,
content: `Seeded notification ${i + 1} for user ${user.id} at ${restaurant.slug}`,
});
em.persist(notif);
}
}
}
await em.flush();
}
}
+52
View File
@@ -0,0 +1,52 @@
import type { EntityManager } from '@mikro-orm/core';
import { PaymentMethod } from '../modules/payments/entities/payment-method.entity';
import type { Restaurant } from '../modules/restaurants/entities/restaurant.entity';
import { paymentMethodsData } from './data/payment-methods.data';
export class PaymentMethodsSeeder {
async run(em: EntityManager, restaurants: Restaurant[]): Promise<void> {
for (const restaurant of restaurants) {
if (!restaurant) continue;
for (const methodData of paymentMethodsData) {
const existing = await em.findOne(PaymentMethod, {
restaurant: { id: restaurant.id },
method: methodData.method,
});
if (!existing) {
const paymentMethod = em.create(PaymentMethod, {
restaurant,
method: methodData.method,
description: methodData.description,
enabled: methodData.enabled,
order: methodData.order,
gateway: methodData.gateway,
merchantId: methodData.merchantId,
});
em.persist(paymentMethod);
} else {
// Update existing payment method if needed
if (
existing.description !== methodData.description ||
existing.enabled !== methodData.enabled ||
existing.order !== methodData.order
) {
existing.description = methodData.description;
existing.enabled = methodData.enabled;
existing.order = methodData.order;
if (methodData.gateway !== undefined) {
existing.gateway = methodData.gateway;
}
if (methodData.merchantId !== undefined) {
existing.merchantId = methodData.merchantId;
}
em.persist(existing);
}
}
}
}
await em.flush();
}
}
+28
View File
@@ -0,0 +1,28 @@
import type { EntityManager } from '@mikro-orm/core';
import { Permission as PermissionEntity } from '../modules/roles/entities/permission.entity';
import { getPermissionsData } from './data/permissions.data';
export class PermissionsSeeder {
async run(em: EntityManager): Promise<PermissionEntity[]> {
const permissions = getPermissionsData();
const createdPermissions: PermissionEntity[] = [];
for (const permData of permissions) {
let permission = await em.findOne(PermissionEntity, { name: permData.name });
if (!permission) {
permission = em.create(PermissionEntity, permData);
em.persist(permission);
} else {
// Update existing permission's title if it changed
if (permission.title !== permData.title) {
permission.title = permData.title;
em.persist(permission);
}
}
createdPermissions.push(permission);
}
await em.flush();
return createdPermissions;
}
}
+26
View File
@@ -0,0 +1,26 @@
import type { EntityManager } from '@mikro-orm/core';
import { Restaurant } from '../modules/restaurants/entities/restaurant.entity';
import { restaurantsData } from './data/restaurants.data';
export class RestaurantsSeeder {
async run(em: EntityManager): Promise<Map<string, Restaurant>> {
const restaurantsMap = new Map<string, Restaurant>();
for (const restaurantData of restaurantsData) {
let restaurant = await em.findOne(Restaurant, { slug: restaurantData.slug });
if (!restaurant) {
restaurant = em.create(Restaurant, {
...restaurantData,
subscriptionStartDate: new Date('2026-01-01'),
subscriptionEndDate: new Date('2026-01-07'),
isActive: true,
});
em.persist(restaurant);
}
restaurantsMap.set(restaurantData.slug, restaurant);
}
await em.flush();
return restaurantsMap;
}
}
+35
View File
@@ -0,0 +1,35 @@
import type { EntityManager } from '@mikro-orm/core';
import { Role } from '../modules/roles/entities/role.entity';
import type { Permission } from '../common/enums/permission.enum';
import type { Permission as PermissionEntity } from '../modules/roles/entities/permission.entity';
import { rolesData } from './data/roles.data';
export class RolesSeeder {
async run(em: EntityManager, permissions: PermissionEntity[]): Promise<Map<string, Role>> {
const rolesMap = new Map<string, Role>();
for (const roleConfig of rolesData) {
let role = await em.findOne(Role, { name: roleConfig.name });
if (!role) {
role = em.create(Role, {
name: roleConfig.name,
isSystem: true,
});
// Add permissions based on role configuration
// TypeScript knows role is not null here because we just created it
const newRole = role;
// Use the permission filter for all roles
const filteredPermissions = permissions.filter(p => roleConfig.permissionFilter(p.name as Permission));
filteredPermissions.forEach(p => newRole.permissions.add(p));
em.persist(newRole);
}
// Always add to map, whether existing or newly created
rolesMap.set(roleConfig.name, role);
}
await em.flush();
return rolesMap;
}
}
+38
View File
@@ -0,0 +1,38 @@
import type { EntityManager } from '@mikro-orm/core';
import { Schedule } from '../modules/restaurants/entities/schedule.entity';
import type { Restaurant } from '../modules/restaurants/entities/restaurant.entity';
import { timeSlots } from './data/schedules.data';
export class SchedulesSeeder {
async run(em: EntityManager, restaurants: Restaurant[]): Promise<void> {
for (const restaurant of restaurants) {
if (!restaurant) continue;
// Create schedules for each day (0 = Sunday, 6 = Saturday)
for (let weekDay = 0; weekDay <= 6; weekDay++) {
// Create 3 schedules per day
for (const timeSlot of timeSlots) {
const existing = await em.findOne(Schedule, {
restId: restaurant.id,
weekDay,
openTime: timeSlot.openTime,
closeTime: timeSlot.closeTime,
});
if (!existing) {
const schedule = em.create(Schedule, {
restId: restaurant.id,
weekDay,
openTime: timeSlot.openTime,
closeTime: timeSlot.closeTime,
isActive: true,
});
em.persist(schedule);
}
}
}
}
await em.flush();
}
}
+36
View File
@@ -0,0 +1,36 @@
import type { EntityManager } from '@mikro-orm/core';
import { User } from '../modules/users/entities/user.entity';
import { Restaurant } from '../modules/restaurants/entities/restaurant.entity';
import { WalletTransaction } from '../modules/users/entities/wallet-transaction.entity';
import { WalletTransactionReason, WalletTransactionType } from 'src/modules/users/interface/wallet';
export class UserWalletsSeeder {
async run(em: EntityManager): Promise<void> {
const users = await em.find(User, {});
const restaurants = await em.find(Restaurant, {});
for (const user of users) {
for (const restaurant of restaurants) {
// Check if wallet already exists for this user-restaurant combination
const existingWallet = await em.findOne(WalletTransaction, {
user: { id: user.id },
restaurant: { id: restaurant.id },
});
if (!existingWallet) {
const wallet = em.create(WalletTransaction, {
user,
restaurant,
balance: 150000000,
amount: 150000000,
type: WalletTransactionType.CREDIT,
reason: WalletTransactionReason.DEPOSIT,
});
em.persist(wallet);
}
}
}
await em.flush();
}
}
+78
View File
@@ -0,0 +1,78 @@
import type { EntityManager } from '@mikro-orm/core';
import { User } from '../modules/users/entities/user.entity';
import { UserAddress } from '../modules/users/entities/user-address.entity';
import { usersData } from './data/users.data';
import { userAddressesData } from './data/user-addresses.data';
import { normalizePhone } from '../modules/utils/phone.util';
export class UsersSeeder {
async run(em: EntityManager): Promise<Map<string, User>> {
const usersMap = new Map<string, User>();
// Create users
for (const userData of usersData) {
const normalizedPhone = normalizePhone(userData.phone);
let user = await em.findOne(User, { phone: normalizedPhone });
if (!user) {
user = em.create(User, {
phone: normalizedPhone, // Use normalized phone
firstName: userData.firstName,
lastName: userData.lastName,
birthDate: new Date(userData.birthDate),
marriageDate: new Date(userData.marriageDate),
isActive: userData.isActive,
gender: userData.gender,
});
em.persist(user);
}
usersMap.set(normalizedPhone, user); // Use normalized phone as key
}
await em.flush();
// Create addresses for users
for (const addressData of userAddressesData) {
const normalizedPhone = normalizePhone(addressData.userPhone);
const user = usersMap.get(normalizedPhone);
if (!user) continue;
// Check if address already exists for this user
const existingAddress = await em.findOne(UserAddress, {
user: { id: user.id },
title: addressData.title,
address: addressData.address,
});
if (!existingAddress) {
// If setting as default, unset other default addresses for this user
if (addressData.isDefault) {
const existingDefaultAddresses = await em.find(UserAddress, {
user: { id: user.id },
isDefault: true,
});
for (const defaultAddress of existingDefaultAddresses) {
defaultAddress.isDefault = false;
em.persist(defaultAddress);
}
}
const address = em.create(UserAddress, {
user,
title: addressData.title,
address: addressData.address,
city: addressData.city,
province: addressData.province,
postalCode: addressData.postalCode,
latitude: addressData.latitude,
longitude: addressData.longitude,
phone: addressData.phone,
isDefault: addressData.isDefault,
});
em.persist(address);
}
}
await em.flush();
return usersMap;
}
}