add: endpoints to create admin for restuarant
This commit is contained in:
@@ -0,0 +1,24 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||||
|
|
||||||
|
export class CreateMyRestaurantAdminDto {
|
||||||
|
@ApiProperty({ description: 'Mobile phone number' })
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
phone!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: 'First name', required: false })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
firstName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: 'Last name', required: false })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
lastName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: 'Role id for the admin' })
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsString()
|
||||||
|
roleId!: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { IsString, IsOptional, IsNumber, IsEnum, IsDate } from 'class-validator';
|
||||||
|
import { Type } from 'class-transformer';
|
||||||
|
import { PlanEnum } from '../interface/plan.interface';
|
||||||
|
|
||||||
|
export class UpdateRestaurantDto {
|
||||||
|
@ApiPropertyOptional({ example: 'کافه ژیوان', description: 'نام رستوران' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
name?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'zhivan', description: 'شناسه (slug) رستوران، لاتین و بدون فاصله' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
slug?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 2020, description: 'سال تأسیس' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
establishedYear?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: '09123456789', description: 'شماره تلفن' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
phone?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'base', enum: PlanEnum, description: 'پلن رستوران' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsEnum(PlanEnum)
|
||||||
|
plan?: PlanEnum;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: 'sub_1234567890', description: 'شناسه اشتراک' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
subscriptionId?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: '2025-12-26', description: 'تاریخ انقضای اشتراک' })
|
||||||
|
@IsOptional()
|
||||||
|
@Type(() => Date)
|
||||||
|
@IsDate()
|
||||||
|
subscriptionEndDate?: Date;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ example: '2025-12-26', description: 'تاریخ شروع اشتراک' })
|
||||||
|
@IsOptional()
|
||||||
|
@Type(() => Date)
|
||||||
|
@IsDate()
|
||||||
|
subscriptionStartDate?: Date;
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@ import { CreateGroupDto } from "./DTO/create-group.dto";
|
|||||||
import { UpdateGroupDto } from "./DTO/update-group.dto";
|
import { UpdateGroupDto } from "./DTO/update-group.dto";
|
||||||
import { FindRestaurantsDto } from "./DTO/find-restaurants.dto";
|
import { FindRestaurantsDto } from "./DTO/find-restaurants.dto";
|
||||||
import { SetupRestaurantDto } from "./DTO/create-restaurant.dto";
|
import { SetupRestaurantDto } from "./DTO/create-restaurant.dto";
|
||||||
|
import { UpdateRestaurantDto } from "./DTO/update-restaurant.dto";
|
||||||
|
import { CreateMyRestaurantAdminDto } from "./DTO/create-restaurant-admin.dto";
|
||||||
import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
|
import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
|
||||||
import { PermissionsDec } from "../../common/decorators/permission.decorator";
|
import { PermissionsDec } from "../../common/decorators/permission.decorator";
|
||||||
import { PermissionEnum } from "../users/enums/permission.enum";
|
import { PermissionEnum } from "../users/enums/permission.enum";
|
||||||
@@ -126,7 +128,7 @@ export class DmenuController {
|
|||||||
|
|
||||||
|
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Get('super-admin/restaurants/sms-count')
|
@Get('admin/dmenu/restaurants/sms-count')
|
||||||
@ApiOperation({ summary: 'Get SMS count for each restaurant with pagination' })
|
@ApiOperation({ summary: 'Get SMS count for each restaurant with pagination' })
|
||||||
@ApiQuery({ name: 'page', required: false, type: Number, description: 'Page number (default: 1)', minimum: 1 })
|
@ApiQuery({ name: 'page', required: false, type: Number, description: 'Page number (default: 1)', minimum: 1 })
|
||||||
@ApiQuery({ name: 'limit', required: false, type: Number, description: 'Items per page (default: 10)', minimum: 1 })
|
@ApiQuery({ name: 'limit', required: false, type: Number, description: 'Items per page (default: 10)', minimum: 1 })
|
||||||
@@ -139,9 +141,47 @@ export class DmenuController {
|
|||||||
return await this.restaurantService.getSmsCountByRestaurant(parsedPage, parsedLimit);
|
return await this.restaurantService.getSmsCountByRestaurant(parsedPage, parsedLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
//here
|
@PermissionsDec(PermissionEnum.DMENU)
|
||||||
|
@Patch('admin/dmenu/restaurants/:id')
|
||||||
|
@ApiOperation({ summary: "Update restaurant" })
|
||||||
|
@ApiParam({ name: "id", required: true, type: String })
|
||||||
|
updateRestaurant(@Param("id") id: string, @Body() dto: UpdateRestaurantDto) {
|
||||||
|
return this.restaurantService.updateRestaurant(id, dto);
|
||||||
|
}
|
||||||
|
|
||||||
//User Endpoints
|
@PermissionsDec(PermissionEnum.DMENU)
|
||||||
|
@Get('admin/dmenu/system-roles')
|
||||||
|
@ApiOperation({ summary: "Get system roles" })
|
||||||
|
getSystemRoles() {
|
||||||
|
return this.restaurantService.getSystemRoles();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PermissionsDec(PermissionEnum.DMENU)
|
||||||
|
@Get('admin/dmenu/restaurants/:restaurantId/admins')
|
||||||
|
@ApiOperation({ summary: "Get restaurant admins" })
|
||||||
|
@ApiParam({ name: "restaurantId", required: true, type: String })
|
||||||
|
getRestaurantAdmins(@Param("restaurantId") restaurantId: string) {
|
||||||
|
return this.restaurantService.getRestaurantAdmins(restaurantId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PermissionsDec(PermissionEnum.DMENU)
|
||||||
|
@Post('admin/dmenu/restaurants/:restaurantId/admins')
|
||||||
|
@ApiOperation({ summary: "Assign admin to restaurant" })
|
||||||
|
@ApiParam({ name: "restaurantId", required: true, type: String })
|
||||||
|
assignRestaurantAdmin(@Param("restaurantId") restaurantId: string, @Body() dto: CreateMyRestaurantAdminDto) {
|
||||||
|
return this.restaurantService.assignRestaurantAdmin(restaurantId, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PermissionsDec(PermissionEnum.DMENU)
|
||||||
|
@Delete('admin/dmenu/restaurants/:restaurantId/admins/:adminId')
|
||||||
|
@ApiOperation({ summary: "Revoke admin from restaurant" })
|
||||||
|
@ApiParam({ name: "restaurantId", required: true, type: String })
|
||||||
|
@ApiParam({ name: "adminId", required: true, type: String })
|
||||||
|
revokeRestaurantAdmin(@Param("restaurantId") restaurantId: string, @Param("adminId") adminId: string) {
|
||||||
|
return this.restaurantService.revokeRestaurantAdmin(restaurantId, adminId);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***User Endpoints***
|
||||||
@Post('dmenu/restaurants')
|
@Post('dmenu/restaurants')
|
||||||
@ApiOperation({ summary: "Create restaurant" })
|
@ApiOperation({ summary: "Create restaurant" })
|
||||||
createRestaurant(@Body() dto: SetupRestaurantDto, @UserDec("id") userId: string) {
|
createRestaurant(@Body() dto: SetupRestaurantDto, @UserDec("id") userId: string) {
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import { IDmenuConfig } from "../../../configs/icons.config";
|
|||||||
import { DMENU_CONFIG } from "../constants";
|
import { DMENU_CONFIG } from "../constants";
|
||||||
import { FindRestaurantsDto } from "../DTO/find-restaurants.dto";
|
import { FindRestaurantsDto } from "../DTO/find-restaurants.dto";
|
||||||
import { SetupRestaurantDto } from "../DTO/create-restaurant.dto";
|
import { SetupRestaurantDto } from "../DTO/create-restaurant.dto";
|
||||||
|
import { UpdateRestaurantDto } from "../DTO/update-restaurant.dto";
|
||||||
|
import { CreateMyRestaurantAdminDto } from "../DTO/create-restaurant-admin.dto";
|
||||||
import { PlanEnum, ISetupRestaurant } from "../interface/plan.interface";
|
import { PlanEnum, ISetupRestaurant } from "../interface/plan.interface";
|
||||||
import { SubscriptionsService } from "../../subscriptions/providers/subscriptions.service";
|
import { SubscriptionsService } from "../../subscriptions/providers/subscriptions.service";
|
||||||
import { SubscriptionMessage } from "../../../common/enums/message.enum";
|
import { SubscriptionMessage } from "../../../common/enums/message.enum";
|
||||||
@@ -125,6 +127,35 @@ export class RestaurantService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateRestaurant(id: string, dto: UpdateRestaurantDto) {
|
||||||
|
try {
|
||||||
|
const { data } = await firstValueFrom(
|
||||||
|
this.httpService
|
||||||
|
.patch(`${this.config.baseUrl}/super-admin/restaurants/${id}`, dto, {
|
||||||
|
headers: this.getHeaders(),
|
||||||
|
})
|
||||||
|
.pipe(
|
||||||
|
catchError((err: AxiosError) => {
|
||||||
|
this.logger.error(`Failed to update restaurant: ${err.message}`, err.stack);
|
||||||
|
return throwError(() => err);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof AxiosError && error.response) {
|
||||||
|
this.logger.error(`External API error response:`, error.response.data);
|
||||||
|
const errorResponse = {
|
||||||
|
...error.response.data,
|
||||||
|
message: error.response.data.error?.message || error.message,
|
||||||
|
};
|
||||||
|
throw new HttpException(errorResponse, error.response.status);
|
||||||
|
}
|
||||||
|
this.logger.error(`Error updating restaurant: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async getRestaurantSubscription(subscriptionId: string) {
|
async getRestaurantSubscription(subscriptionId: string) {
|
||||||
try {
|
try {
|
||||||
const { data } = await firstValueFrom(
|
const { data } = await firstValueFrom(
|
||||||
@@ -183,5 +214,121 @@ export class RestaurantService {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getSystemRoles() {
|
||||||
|
try {
|
||||||
|
const { data } = await firstValueFrom(
|
||||||
|
this.httpService
|
||||||
|
.get(`${this.config.baseUrl}/super-admin/system-roles`, {
|
||||||
|
headers: this.getHeaders(),
|
||||||
|
})
|
||||||
|
.pipe(
|
||||||
|
catchError((err: AxiosError) => {
|
||||||
|
this.logger.error(`Failed to get system roles: ${err.message}`, err.stack);
|
||||||
|
return throwError(() => err);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof AxiosError && error.response) {
|
||||||
|
this.logger.error(`External API error response:`, error.response.data);
|
||||||
|
const errorResponse = {
|
||||||
|
...error.response.data,
|
||||||
|
message: error.response.data.error?.message || error.message,
|
||||||
|
};
|
||||||
|
throw new HttpException(errorResponse, error.response.status);
|
||||||
|
}
|
||||||
|
this.logger.error(`Error getting system roles: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRestaurantAdmins(restaurantId: string) {
|
||||||
|
try {
|
||||||
|
const { data } = await firstValueFrom(
|
||||||
|
this.httpService
|
||||||
|
.get(`${this.config.baseUrl}/super-admin/restaurants/${restaurantId}/admins`, {
|
||||||
|
headers: this.getHeaders(),
|
||||||
|
})
|
||||||
|
.pipe(
|
||||||
|
catchError((err: AxiosError) => {
|
||||||
|
this.logger.error(`Failed to get restaurant admins: ${err.message}`, err.stack);
|
||||||
|
return throwError(() => err);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof AxiosError && error.response) {
|
||||||
|
this.logger.error(`External API error response:`, error.response.data);
|
||||||
|
const errorResponse = {
|
||||||
|
...error.response.data,
|
||||||
|
message: error.response.data.error?.message || error.message,
|
||||||
|
};
|
||||||
|
throw new HttpException(errorResponse, error.response.status);
|
||||||
|
}
|
||||||
|
this.logger.error(`Error getting restaurant admins: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async revokeRestaurantAdmin(restaurantId: string, adminId: string) {
|
||||||
|
try {
|
||||||
|
const { data } = await firstValueFrom(
|
||||||
|
this.httpService
|
||||||
|
.delete(`${this.config.baseUrl}/super-admin/restaurants/${restaurantId}/admins/${adminId}`, {
|
||||||
|
headers: this.getHeaders(),
|
||||||
|
})
|
||||||
|
.pipe(
|
||||||
|
catchError((err: AxiosError) => {
|
||||||
|
this.logger.error(`Failed to revoke restaurant admin: ${err.message}`, err.stack);
|
||||||
|
return throwError(() => err);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof AxiosError && error.response) {
|
||||||
|
this.logger.error(`External API error response:`, error.response.data);
|
||||||
|
const errorResponse = {
|
||||||
|
...error.response.data,
|
||||||
|
message: error.response.data.error?.message || error.message,
|
||||||
|
};
|
||||||
|
throw new HttpException(errorResponse, error.response.status);
|
||||||
|
}
|
||||||
|
this.logger.error(`Error revoking restaurant admin: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async assignRestaurantAdmin(restaurantId: string, dto: CreateMyRestaurantAdminDto) {
|
||||||
|
try {
|
||||||
|
const { data } = await firstValueFrom(
|
||||||
|
this.httpService
|
||||||
|
.post(`${this.config.baseUrl}/super-admin/restaurants/${restaurantId}/admins`, dto, {
|
||||||
|
headers: this.getHeaders(),
|
||||||
|
})
|
||||||
|
.pipe(
|
||||||
|
catchError((err: AxiosError) => {
|
||||||
|
this.logger.error(`Failed to assign restaurant admin: ${err.message}`, err.stack);
|
||||||
|
return throwError(() => err);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof AxiosError && error.response) {
|
||||||
|
this.logger.error(`External API error response:`, error.response.data);
|
||||||
|
const errorResponse = {
|
||||||
|
...error.response.data,
|
||||||
|
message: error.response.data.error?.message || error.message,
|
||||||
|
};
|
||||||
|
throw new HttpException(errorResponse, error.response.status);
|
||||||
|
}
|
||||||
|
this.logger.error(`Error assigning restaurant admin: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user