diff --git a/src/modules/restaurants/controllers/restaurants.controller.ts b/src/modules/restaurants/controllers/restaurants.controller.ts index 4687119..27d684a 100644 --- a/src/modules/restaurants/controllers/restaurants.controller.ts +++ b/src/modules/restaurants/controllers/restaurants.controller.ts @@ -77,8 +77,7 @@ export class RestaurantsController { @ApiOperation({ summary: 'Create a new restaurant' }) @Post('super-admin/restaurants') createRestaurant(@Body() createRestaurantDto: CreateRestaurantDto) { - console.log('create rest') - return this.restaurantsService.create(createRestaurantDto); + return this.restaurantsService.setupRestuarant(createRestaurantDto); } @UseGuards(SuperAdminAuthGuard) diff --git a/src/modules/restaurants/dto/create-restaurant.dto.ts b/src/modules/restaurants/dto/create-restaurant.dto.ts index 50f1f9d..aeace68 100644 --- a/src/modules/restaurants/dto/create-restaurant.dto.ts +++ b/src/modules/restaurants/dto/create-restaurant.dto.ts @@ -1,6 +1,7 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsString, IsOptional, IsNumber, IsDate } from 'class-validator'; +import { IsString, IsOptional, IsNumber, IsDate, IsEnum } from 'class-validator'; import { Type } from 'class-transformer'; +import { PlanEnum } from '../interface/plan.interface'; export class CreateRestaurantDto { @ApiProperty({ example: 'کافه ژیوان', description: 'نام رستوران' }) @@ -21,6 +22,10 @@ export class CreateRestaurantDto { @IsString() phone: string; + @ApiProperty({ example: 'base', enum: PlanEnum, description: 'پلن رستوران' }) + @IsEnum(PlanEnum) + plan!: PlanEnum; + @ApiProperty({ example: 'sub_1234567890', description: 'شناسه اشتراک' }) @IsString() subscriptionId!: string; diff --git a/src/modules/restaurants/providers/restaurants.service.ts b/src/modules/restaurants/providers/restaurants.service.ts index 924f2c8..1c36308 100644 --- a/src/modules/restaurants/providers/restaurants.service.ts +++ b/src/modules/restaurants/providers/restaurants.service.ts @@ -8,6 +8,9 @@ import { RestMessage } from 'src/common/enums/message.enum'; import { FindRestaurantsDto } from '../dto/find-restaurants.dto'; import { PaginatedResult } from 'src/common/interfaces/pagination.interface'; import { PlanEnum } from '../interface/plan.interface'; +import { Admin } from '../../admin/entities/admin.entity'; +import { AdminRole } from '../../admin/entities/adminRole.entity'; +import { Role } from '../../roles/entities/role.entity'; @Injectable() export class RestaurantsService { @@ -16,30 +19,63 @@ export class RestaurantsService { private readonly restRepository: RestRepository, ) { } - async create(dto: CreateRestaurantDto): Promise { - const validateSlug = await this.em.findOne(Restaurant, { slug: dto.slug }) - if (validateSlug) { - throw new BadRequestException("Duplicate slug: " + dto.slug) - } - const validateSubscriptionId = await this.em.findOne(Restaurant, { subscriptionId: dto.subscriptionId }) - if (validateSubscriptionId) { - throw new BadRequestException("Duplicate subscriptionId: " + dto.subscriptionId) - } - const restaurant = this.em.create(Restaurant, { - name: dto.name, - slug: dto.slug, - establishedYear: dto.establishedYear, - phone: dto.phone, - isActive: true, - plan: PlanEnum.Base, - domain: `https://dmenu-plus-front.dev.danakcorp.com/${dto.slug}`, - subscriptionId: dto.subscriptionId, - subscriptionEndDate: dto.subscriptionEndDate, - subscriptionStartDate: dto.subscriptionStartDate, - }); + async setupRestuarant(dto: CreateRestaurantDto): Promise { + return await this.em.transactional(async (em) => { + // Validate unique constraints + const validateSlug = await em.findOne(Restaurant, { slug: dto.slug }) + if (validateSlug) { + throw new BadRequestException("Duplicate slug: " + dto.slug) + } + const validateSubscriptionId = await em.findOne(Restaurant, { subscriptionId: dto.subscriptionId }) + if (validateSubscriptionId) { + throw new BadRequestException("Duplicate subscriptionId: " + dto.subscriptionId) + } - await this.em.persistAndFlush(restaurant); - return restaurant; + // Create restaurant + const restaurant = em.create(Restaurant, { + name: dto.name, + slug: dto.slug, + establishedYear: dto.establishedYear, + phone: dto.phone, + isActive: true, + plan: dto.plan, + domain: `https://dmenu-plus-front.dev.danakcorp.com/${dto.slug}`, + subscriptionId: dto.subscriptionId, + subscriptionEndDate: dto.subscriptionEndDate, + subscriptionStartDate: dto.subscriptionStartDate, + }); + + // Find the appropriate role based on plan + const roleName = dto.plan === PlanEnum.Base ? 'مدیر (پلن پایه)' : 'مدیر ( پلن ویژه)'; + const role = await em.findOne(Role, { name: roleName }); + if (!role) { + throw new BadRequestException(`Role not found for plan: ${dto.plan}`); + } + + // Create admin (using a default phone number for now - this could be made configurable) + const adminPhone = `admin_${dto.slug}@system.local`; // Temporary phone format for system-generated admins + let admin = await em.findOne(Admin, { phone: adminPhone }); + if (!admin) { + admin = em.create(Admin, { + phone: adminPhone, + firstName: 'مدیر', + lastName: dto.name, + }); + } + + // Create admin role relationship + const adminRole = em.create(AdminRole, { + admin: admin, + role: role, + restaurant: restaurant, + }); + + // Persist all entities + em.persist([restaurant, admin, adminRole]); + await em.flush(); + + return restaurant; + }); } async findAll(dto: FindRestaurantsDto): Promise> { diff --git a/src/seeders/data/admins.data.ts b/src/seeders/data/admins.data.ts index 7992b59..9e5ec90 100644 --- a/src/seeders/data/admins.data.ts +++ b/src/seeders/data/admins.data.ts @@ -11,14 +11,14 @@ export const adminsData: AdminData[] = [ phone: '09362532122', firstName: 'مرتضی', lastName: 'مرتضایی', - roleName: 'restaurant', + roleName: 'مدیر ( پلن ویژه)', restaurantSlug: 'zhivan', }, { phone: '09185290775', firstName: 'حمید', lastName: 'ضرقامی', - roleName: 'restaurant', + roleName: 'مدیر (پلن پایه)', restaurantSlug: 'boote', }, { @@ -32,7 +32,7 @@ export const adminsData: AdminData[] = [ phone: '09184317567', firstName: 'ادمین', lastName: 'هنر', - roleName: 'restaurant', + roleName: 'مدیر (پلن پایه)', restaurantSlug: 'honar', }, ]; diff --git a/src/seeders/data/restaurants.data.ts b/src/seeders/data/restaurants.data.ts index e706cb9..0bcb7cd 100644 --- a/src/seeders/data/restaurants.data.ts +++ b/src/seeders/data/restaurants.data.ts @@ -20,7 +20,7 @@ export interface RestaurantData { marriageDateScore: string; referrerScore: string; }; - plan: PlanEnum.Premium; + plan: PlanEnum; subscriptionId: string; } @@ -84,7 +84,7 @@ export const restaurantsData: RestaurantData[] = [ marriageDateScore: '10000', referrerScore: '10000', }, - plan: PlanEnum.Premium, + plan: PlanEnum.Base, subscriptionId: 'sub_seed_boote_001', }, { @@ -115,7 +115,7 @@ export const restaurantsData: RestaurantData[] = [ marriageDateScore: '10000', referrerScore: '10000', }, - plan: PlanEnum.Premium, + plan: PlanEnum.Base, subscriptionId: 'sub_seed_honar_001', }, ]; diff --git a/src/seeders/data/roles.data.ts b/src/seeders/data/roles.data.ts index faa7412..c2907f5 100644 --- a/src/seeders/data/roles.data.ts +++ b/src/seeders/data/roles.data.ts @@ -8,12 +8,21 @@ export interface RoleConfig { export const rolesData: RoleConfig[] = [ { - name: 'restaurant', + 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: 'مدیر ( پلن ویژه)', isSystem: false, permissionFilter: () => true, // All permissions for restaurant role }, { - name: 'accountant', + name: 'حسابدار ', isSystem: false, permissionFilter: (name: Permission) => name === Permission.VIEW_REPORTS || name === Permission.MANAGE_PAYMENTS || name === Permission.MANAGE_ORDERS,