product module
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
export { UserId } from './user-id.decorator';
|
export { UserId } from './user-id.decorator';
|
||||||
export { RestId } from './rest-id.decorator';
|
export { ShopId } from './rest-id.decorator';
|
||||||
export { RateLimit } from './rate-limit.decorator';
|
export { RateLimit } from './rate-limit.decorator';
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ import { createParamDecorator, type ExecutionContext } from '@nestjs/common';
|
|||||||
import type { Request } from 'express';
|
import type { Request } from 'express';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorator to extract restId from the authenticated request.
|
* Decorator to extract shopId from the authenticated request.
|
||||||
* Must be used after AdminAuthGuard or AuthGuard that sets request.restId.
|
* Must be used after AdminAuthGuard or AuthGuard that sets request.shopId.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* @Get('/shops')
|
* @Get('/shops')
|
||||||
* @UseGuards(AdminAuthGuard)
|
* @UseGuards(AdminAuthGuard)
|
||||||
* getRestaurants(@RestId() restId: string) {
|
* getRestaurants(@shopId() shopId: string) {
|
||||||
* return this.restaurantService.findById(restId);
|
* return this.restaurantService.findById(shopId);
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
export const RestId = createParamDecorator((data: unknown, ctx: ExecutionContext): string => {
|
export const ShopId = createParamDecorator((data: unknown, ctx: ExecutionContext): string => {
|
||||||
const request = ctx.switchToHttp().getRequest<Request & { restId?: string }>();
|
const request = ctx.switchToHttp().getRequest<Request & { shopId?: string }>();
|
||||||
return request.restId || '';
|
return request.shopId || '';
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ import { CreateMyRestaurantAdminDto } from '../dto/create-my-shop-admin.dto';
|
|||||||
@ApiTags('admin')
|
@ApiTags('admin')
|
||||||
@Controller()
|
@Controller()
|
||||||
export class AdminController {
|
export class AdminController {
|
||||||
constructor(private readonly adminService: AdminService) {}
|
constructor(private readonly adminService: AdminService) { }
|
||||||
|
|
||||||
@Get('admin/admins')
|
@Get('admin/admins')
|
||||||
@UseGuards(AdminAuthGuard)
|
@UseGuards(AdminAuthGuard)
|
||||||
@Permissions(Permission.MANAGE_ADMINS)
|
@Permissions(Permission.MANAGE_ADMINS)
|
||||||
@ApiOperation({ summary: 'admin' })
|
@ApiOperation({ summary: 'admin' })
|
||||||
async getAll(@RestId() restId: string) {
|
async getAll(@ShopId() restId: string) {
|
||||||
const admin = await this.adminService.findAllByRestaurantId(restId);
|
const admin = await this.adminService.findAllByRestaurantId(restId);
|
||||||
return admin;
|
return admin;
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ export class AdminController {
|
|||||||
@UseGuards(AdminAuthGuard)
|
@UseGuards(AdminAuthGuard)
|
||||||
@Permissions(Permission.MANAGE_ADMINS)
|
@Permissions(Permission.MANAGE_ADMINS)
|
||||||
@ApiOperation({ summary: 'admin' })
|
@ApiOperation({ summary: 'admin' })
|
||||||
async getMe(@AdminId() adminId: string, @RestId() restId: string) {
|
async getMe(@AdminId() adminId: string, @ShopId() restId: string) {
|
||||||
const admin = await this.adminService.findById(adminId, restId);
|
const admin = await this.adminService.findById(adminId, restId);
|
||||||
return admin;
|
return admin;
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ export class AdminController {
|
|||||||
@HttpCode(HttpStatus.CREATED)
|
@HttpCode(HttpStatus.CREATED)
|
||||||
@ApiOperation({ summary: 'Create a new admin' })
|
@ApiOperation({ summary: 'Create a new admin' })
|
||||||
@ApiBody({ type: CreateAdminDto })
|
@ApiBody({ type: CreateAdminDto })
|
||||||
async create(@Body() dto: CreateAdminDto, @RestId() restId: string) {
|
async create(@Body() dto: CreateAdminDto, @ShopId() restId: string) {
|
||||||
const admin = await this.adminService.createAdminForMyRestaurant(restId, dto);
|
const admin = await this.adminService.createAdminForMyRestaurant(restId, dto);
|
||||||
return admin;
|
return admin;
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ export class AdminController {
|
|||||||
@ApiOperation({ summary: 'Update an admin' })
|
@ApiOperation({ summary: 'Update an admin' })
|
||||||
@ApiParam({ name: 'adminId', description: 'Admin ID' })
|
@ApiParam({ name: 'adminId', description: 'Admin ID' })
|
||||||
@ApiBody({ type: UpdateAdminDto })
|
@ApiBody({ type: UpdateAdminDto })
|
||||||
update(@Param('adminId') adminId: string, @Body() dto: UpdateAdminDto, @RestId() restId: string): Promise<Admin> {
|
update(@Param('adminId') adminId: string, @Body() dto: UpdateAdminDto, @ShopId() restId: string): Promise<Admin> {
|
||||||
return this.adminService.update(adminId, restId, dto);
|
return this.adminService.update(adminId, restId, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ export class AdminController {
|
|||||||
@Permissions(Permission.MANAGE_ADMINS)
|
@Permissions(Permission.MANAGE_ADMINS)
|
||||||
@ApiOperation({ summary: 'Get an admin by ID' })
|
@ApiOperation({ summary: 'Get an admin by ID' })
|
||||||
@ApiParam({ name: 'id', description: 'Admin ID' })
|
@ApiParam({ name: 'id', description: 'Admin ID' })
|
||||||
getById(@Param('adminId') adminId: string, @RestId() restId: string): Promise<Admin | null> {
|
getById(@Param('adminId') adminId: string, @ShopId() restId: string): Promise<Admin | null> {
|
||||||
return this.adminService.findById(adminId, restId);
|
return this.adminService.findById(adminId, restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ export class AdminController {
|
|||||||
@Permissions(Permission.MANAGE_ADMINS)
|
@Permissions(Permission.MANAGE_ADMINS)
|
||||||
@ApiOperation({ summary: 'Delete an admin by ID' })
|
@ApiOperation({ summary: 'Delete an admin by ID' })
|
||||||
@ApiParam({ name: 'id', description: 'Admin ID' })
|
@ApiParam({ name: 'id', description: 'Admin ID' })
|
||||||
deleteById(@Param('adminId') adminId: string, @RestId() restId: string): Promise<void> {
|
deleteById(@Param('adminId') adminId: string, @ShopId() restId: string): Promise<void> {
|
||||||
return this.adminService.remove(adminId, restId);
|
return this.adminService.remove(adminId, restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { ApplyCouponDto } from '../dto/apply-coupon.dto';
|
|||||||
import { ApiTags, ApiOperation, ApiBearerAuth, ApiBody, ApiParam, ApiHeader } from '@nestjs/swagger';
|
import { ApiTags, ApiOperation, ApiBearerAuth, ApiBody, ApiParam, ApiHeader } from '@nestjs/swagger';
|
||||||
import { AuthGuard } from '../../../auth/guards/auth.guard';
|
import { AuthGuard } from '../../../auth/guards/auth.guard';
|
||||||
import { UserId } from 'src/common/decorators/user-id.decorator';
|
import { UserId } from 'src/common/decorators/user-id.decorator';
|
||||||
import { RestId } from 'src/common/decorators/rest-id.decorator';
|
import { ShopId } from 'src/common/decorators/rest-id.decorator';
|
||||||
import { SetAllCartParmsDto } from '../dto/set-all-cart-params.dto';
|
import { SetAllCartParmsDto } from '../dto/set-all-cart-params.dto';
|
||||||
import { API_HEADER_SLUG } from 'src/common/constants/index';
|
import { API_HEADER_SLUG } from 'src/common/constants/index';
|
||||||
|
|
||||||
@@ -14,12 +14,12 @@ import { API_HEADER_SLUG } from 'src/common/constants/index';
|
|||||||
@ApiTags('cart')
|
@ApiTags('cart')
|
||||||
@Controller('public/cart')
|
@Controller('public/cart')
|
||||||
export class CartController {
|
export class CartController {
|
||||||
constructor(private readonly cartService: CartService) {}
|
constructor(private readonly cartService: CartService) { }
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@ApiOperation({ summary: 'Get cart for current user and shop' })
|
@ApiOperation({ summary: 'Get cart for current user and shop' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
async findOne(@UserId() userId: string, @RestId() restaurantId: string) {
|
async findOne(@UserId() userId: string, @ShopId() restaurantId: string) {
|
||||||
return this.cartService.getOrCreateCart(userId, restaurantId);
|
return this.cartService.getOrCreateCart(userId, restaurantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ export class CartController {
|
|||||||
@ApiOperation({ summary: 'Increment item quantity in cart by 1' })
|
@ApiOperation({ summary: 'Increment item quantity in cart by 1' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiParam({ name: 'foodId', description: 'Product ID to increment in cart' })
|
@ApiParam({ name: 'foodId', description: 'Product ID to increment in cart' })
|
||||||
async incrementItem(@UserId() userId: string, @RestId() restaurantId: string, @Param('foodId') foodId: string) {
|
async incrementItem(@UserId() userId: string, @ShopId() restaurantId: string, @Param('foodId') foodId: string) {
|
||||||
return this.cartService.incrementItem(userId, restaurantId, foodId, 1);
|
return this.cartService.incrementItem(userId, restaurantId, foodId, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ export class CartController {
|
|||||||
@ApiOperation({ summary: 'Decrement item quantity in cart by 1 (removes item if quantity reaches 0)' })
|
@ApiOperation({ summary: 'Decrement item quantity in cart by 1 (removes item if quantity reaches 0)' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiParam({ name: 'foodId', description: 'Product ID to decrement in cart' })
|
@ApiParam({ name: 'foodId', description: 'Product ID to decrement in cart' })
|
||||||
async decrementItem(@UserId() userId: string, @RestId() restaurantId: string, @Param('foodId') foodId: string) {
|
async decrementItem(@UserId() userId: string, @ShopId() restaurantId: string, @Param('foodId') foodId: string) {
|
||||||
return this.cartService.decrementItem(userId, restaurantId, foodId);
|
return this.cartService.decrementItem(userId, restaurantId, foodId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ export class CartController {
|
|||||||
@ApiBody({ type: BulkAddItemsToCartDto })
|
@ApiBody({ type: BulkAddItemsToCartDto })
|
||||||
bulkAddItems(
|
bulkAddItems(
|
||||||
@UserId() userId: string,
|
@UserId() userId: string,
|
||||||
@RestId() restaurantId: string,
|
@ShopId() restaurantId: string,
|
||||||
@Body() bulkAddItemsDto: BulkAddItemsToCartDto,
|
@Body() bulkAddItemsDto: BulkAddItemsToCartDto,
|
||||||
) {
|
) {
|
||||||
return this.cartService.bulkAddItems(userId, restaurantId, bulkAddItemsDto);
|
return this.cartService.bulkAddItems(userId, restaurantId, bulkAddItemsDto);
|
||||||
@@ -55,14 +55,14 @@ export class CartController {
|
|||||||
@ApiOperation({ summary: 'Remove item from cart' })
|
@ApiOperation({ summary: 'Remove item from cart' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiParam({ name: 'foodId', description: 'Product ID in the cart' })
|
@ApiParam({ name: 'foodId', description: 'Product ID in the cart' })
|
||||||
async removeItem(@UserId() userId: string, @RestId() restaurantId: string, @Param('foodId') foodId: string) {
|
async removeItem(@UserId() userId: string, @ShopId() restaurantId: string, @Param('foodId') foodId: string) {
|
||||||
return this.cartService.removeItem(userId, restaurantId, foodId);
|
return this.cartService.removeItem(userId, restaurantId, foodId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete()
|
@Delete()
|
||||||
@ApiOperation({ summary: 'Clear entire cart' })
|
@ApiOperation({ summary: 'Clear entire cart' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
async clearCart(@UserId() userId: string, @RestId() restaurantId: string) {
|
async clearCart(@UserId() userId: string, @ShopId() restaurantId: string) {
|
||||||
return this.cartService.clearCart(userId, restaurantId);
|
return this.cartService.clearCart(userId, restaurantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,14 +70,14 @@ export class CartController {
|
|||||||
@ApiOperation({ summary: 'Apply coupon to cart' })
|
@ApiOperation({ summary: 'Apply coupon to cart' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiBody({ type: ApplyCouponDto })
|
@ApiBody({ type: ApplyCouponDto })
|
||||||
async applyCoupon(@UserId() userId: string, @RestId() restaurantId: string, @Body() applyCouponDto: ApplyCouponDto) {
|
async applyCoupon(@UserId() userId: string, @ShopId() restaurantId: string, @Body() applyCouponDto: ApplyCouponDto) {
|
||||||
return this.cartService.applyCoupon(userId, restaurantId, applyCouponDto);
|
return this.cartService.applyCoupon(userId, restaurantId, applyCouponDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete('coupon')
|
@Delete('coupon')
|
||||||
@ApiOperation({ summary: 'Remove coupon from cart' })
|
@ApiOperation({ summary: 'Remove coupon from cart' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
async removeCoupon(@UserId() userId: string, @RestId() restaurantId: string) {
|
async removeCoupon(@UserId() userId: string, @ShopId() restaurantId: string) {
|
||||||
return this.cartService.removeCoupon(userId, restaurantId);
|
return this.cartService.removeCoupon(userId, restaurantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ export class CartController {
|
|||||||
@ApiOperation({ summary: 'Set all cart params' })
|
@ApiOperation({ summary: 'Set all cart params' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiBody({ type: SetAllCartParmsDto })
|
@ApiBody({ type: SetAllCartParmsDto })
|
||||||
setAllCartParams(@UserId() userId: string, @RestId() restaurantId: string, @Body() dto: SetAllCartParmsDto) {
|
setAllCartParams(@UserId() userId: string, @ShopId() restaurantId: string, @Body() dto: SetAllCartParmsDto) {
|
||||||
return this.cartService.setAllCartParams(userId, restaurantId, dto);
|
return this.cartService.setAllCartParams(userId, restaurantId, dto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { OptionalAuthGuard } from 'src/modules/auth/guards/optinalAuth.guard';
|
|||||||
import { API_HEADER_SLUG } from 'src/common/constants';
|
import { API_HEADER_SLUG } from 'src/common/constants';
|
||||||
import { Permission } from 'src/common/enums/permission.enum';
|
import { Permission } from 'src/common/enums/permission.enum';
|
||||||
import { Permissions } from 'src/common/decorators/permissions.decorator';
|
import { Permissions } from 'src/common/decorators/permissions.decorator';
|
||||||
import { RestId } from 'src/common/decorators/rest-id.decorator';
|
import { ShopId } from 'src/common/decorators/rest-id.decorator';
|
||||||
import { RestSlug } from 'src/common/decorators/rest-slug.decorator';
|
import { RestSlug } from 'src/common/decorators/rest-slug.decorator';
|
||||||
|
|
||||||
@ApiTags('contact')
|
@ApiTags('contact')
|
||||||
@@ -32,7 +32,7 @@ export class ContactController {
|
|||||||
@Post('public/contact')
|
@Post('public/contact')
|
||||||
@ApiOperation({ summary: 'Create a new contact (public endpoint)' })
|
@ApiOperation({ summary: 'Create a new contact (public endpoint)' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
async create(@Body() createContactDto: CreateContactDto, @RestSlug() slug: string, @RestId() restId?: string) {
|
async create(@Body() createContactDto: CreateContactDto, @RestSlug() slug: string, @ShopId() restId?: string) {
|
||||||
return this.contactService.create(createContactDto, restId, slug);
|
return this.contactService.create(createContactDto, restId, slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ export class ContactController {
|
|||||||
@ApiQuery({ name: 'orderBy', required: false, type: String })
|
@ApiQuery({ name: 'orderBy', required: false, type: String })
|
||||||
@ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
|
@ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
|
||||||
@ApiQuery({ name: 'status', required: false, enum: ['new', 'seen'] })
|
@ApiQuery({ name: 'status', required: false, enum: ['new', 'seen'] })
|
||||||
async findAllPaginated(@RestId() restId: string, @Query() dto: FindContactsDto) {
|
async findAllPaginated(@ShopId() restId: string, @Query() dto: FindContactsDto) {
|
||||||
return this.contactService.findAllPaginatedAdmin(dto, restId);
|
return this.contactService.findAllPaginatedAdmin(dto, restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ export class ContactController {
|
|||||||
@Get('admin/contact/:id')
|
@Get('admin/contact/:id')
|
||||||
@ApiOperation({ summary: 'Get contact details by ID (admin only)' })
|
@ApiOperation({ summary: 'Get contact details by ID (admin only)' })
|
||||||
@ApiParam({ name: 'id', description: 'Contact ID' })
|
@ApiParam({ name: 'id', description: 'Contact ID' })
|
||||||
async findOne(@RestId() restId: string, @Param('id') id: string) {
|
async findOne(@ShopId() restId: string, @Param('id') id: string) {
|
||||||
return this.contactService.findOne(id, restId);
|
return this.contactService.findOne(id, restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ export class ContactController {
|
|||||||
@Patch('admin/contact/:id/status')
|
@Patch('admin/contact/:id/status')
|
||||||
@ApiOperation({ summary: 'Update contact status (admin only)' })
|
@ApiOperation({ summary: 'Update contact status (admin only)' })
|
||||||
@ApiParam({ name: 'id', description: 'Contact ID' })
|
@ApiParam({ name: 'id', description: 'Contact ID' })
|
||||||
async updateStatus(@RestId() restId: string, @Param('id') id: string, @Body() dto: UpdateContactStatusDto) {
|
async updateStatus(@ShopId() restId: string, @Param('id') id: string, @Body() dto: UpdateContactStatusDto) {
|
||||||
return this.contactService.updateStatus(id, dto, restId);
|
return this.contactService.updateStatus(id, dto, restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ export class ContactController {
|
|||||||
@Delete('admin/contact/:id')
|
@Delete('admin/contact/:id')
|
||||||
@ApiOperation({ summary: 'Hard delete a contact (admin only)' })
|
@ApiOperation({ summary: 'Hard delete a contact (admin only)' })
|
||||||
@ApiParam({ name: 'id', description: 'Contact ID' })
|
@ApiParam({ name: 'id', description: 'Contact ID' })
|
||||||
async remove(@RestId() restId: string, @Param('id') id: string) {
|
async remove(@ShopId() restId: string, @Param('id') id: string) {
|
||||||
await this.contactService.remove(id, restId);
|
await this.contactService.remove(id, restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export class CouponController {
|
|||||||
@ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
|
@ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
|
||||||
@ApiQuery({ name: 'type', required: false, enum: ['PERCENTAGE', 'FIXED'] })
|
@ApiQuery({ name: 'type', required: false, enum: ['PERCENTAGE', 'FIXED'] })
|
||||||
@ApiQuery({ name: 'isActive', required: false, type: Boolean })
|
@ApiQuery({ name: 'isActive', required: false, type: Boolean })
|
||||||
getMyCoupons(@Query() dto: FindCouponsDto, @RestId() restId: string) {
|
getMyCoupons(@Query() dto: FindCouponsDto, @ShopId() restId: string) {
|
||||||
return this.couponService.findAll(restId, dto);
|
return this.couponService.findAll(restId, dto);
|
||||||
}
|
}
|
||||||
/*** Admin ***/
|
/*** Admin ***/
|
||||||
@@ -50,7 +50,7 @@ export class CouponController {
|
|||||||
@ApiOperation({ summary: 'Create a new coupon' })
|
@ApiOperation({ summary: 'Create a new coupon' })
|
||||||
@ApiCreatedResponse({ description: 'The coupon has been successfully created.', type: CreateCouponDto })
|
@ApiCreatedResponse({ description: 'The coupon has been successfully created.', type: CreateCouponDto })
|
||||||
@ApiBody({ type: CreateCouponDto })
|
@ApiBody({ type: CreateCouponDto })
|
||||||
create(@Body() createCouponDto: CreateCouponDto, @RestId() restId: string) {
|
create(@Body() createCouponDto: CreateCouponDto, @ShopId() restId: string) {
|
||||||
return this.couponService.create(restId, createCouponDto);
|
return this.couponService.create(restId, createCouponDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ export class CouponController {
|
|||||||
@ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
|
@ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
|
||||||
@ApiQuery({ name: 'type', required: false, enum: ['PERCENTAGE', 'FIXED'] })
|
@ApiQuery({ name: 'type', required: false, enum: ['PERCENTAGE', 'FIXED'] })
|
||||||
@ApiQuery({ name: 'isActive', required: false, type: Boolean })
|
@ApiQuery({ name: 'isActive', required: false, type: Boolean })
|
||||||
findAll(@Query() dto: FindCouponsDto, @RestId() restId: string) {
|
findAll(@Query() dto: FindCouponsDto, @ShopId() restId: string) {
|
||||||
return this.couponService.findAll(restId, dto);
|
return this.couponService.findAll(restId, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ export class CouponController {
|
|||||||
@Permissions(Permission.MANAGE_COUPONS)
|
@Permissions(Permission.MANAGE_COUPONS)
|
||||||
@Get('admin/coupons/generate-code')
|
@Get('admin/coupons/generate-code')
|
||||||
@ApiOperation({ summary: 'generate a coupon code' })
|
@ApiOperation({ summary: 'generate a coupon code' })
|
||||||
generateCouponCode(@RestId() restId: string) {
|
generateCouponCode(@ShopId() restId: string) {
|
||||||
return this.couponService.generateCouponCode(restId);
|
return this.couponService.generateCouponCode(restId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Entity, Index, ManyToOne, Property, Enum, Unique } from '@mikro-orm/core';
|
import { Entity, Index, ManyToOne, Property, Enum, Unique } from '@mikro-orm/core';
|
||||||
import { BaseEntity } from '../../../../common/entities/base.entity';
|
import { BaseEntity } from '../../../../common/entities/base.entity';
|
||||||
import { Shop } from ../../../shops/entities/shop.entity';
|
import { Shop } from ../../../ shops / entities / shop.entity';
|
||||||
import { normalizePhone } from '../../../utils/phone.util';
|
import { normalizePhone } from '../../../utils/phone.util';
|
||||||
import { CouponType } from '../interface/coupon';
|
import { CouponType } from '../interface/coupon';
|
||||||
|
|
||||||
@@ -25,13 +25,13 @@ export class Coupon extends BaseEntity {
|
|||||||
@Enum(() => CouponType)
|
@Enum(() => CouponType)
|
||||||
type!: CouponType;
|
type!: CouponType;
|
||||||
|
|
||||||
@Property({ type: 'decimal', precision: 10, scale: 2 })
|
@Property({ type: 'decimal', precision: 10, scale: 0 })
|
||||||
value!: number; // Discount amount or percentage
|
value!: number; // Discount amount or percentage
|
||||||
|
|
||||||
@Property({ type: 'decimal', precision: 10, scale: 2, nullable: true })
|
@Property({ type: 'decimal', precision: 10, scale: 0, nullable: true })
|
||||||
maxDiscount?: number; // Maximum discount for percentage coupons
|
maxDiscount?: number; // Maximum discount for percentage coupons
|
||||||
|
|
||||||
@Property({ type: 'decimal', precision: 10, scale: 2, nullable: true })
|
@Property({ type: 'decimal', precision: 10, scale: 0, nullable: true })
|
||||||
minOrderAmount?: number; // Minimum order amount to use coupon
|
minOrderAmount?: number; // Minimum order amount to use coupon
|
||||||
|
|
||||||
@Property({ type: 'int', nullable: true })
|
@Property({ type: 'int', nullable: true })
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
import { DeliveryService } from '../providers/delivery.service';
|
import { DeliveryService } from '../providers/delivery.service';
|
||||||
import { CreateDeliveryDto } from '../dto/create-delivery.dto';
|
import { CreateDeliveryDto } from '../dto/create-delivery.dto';
|
||||||
import { UpdateDeliveryDto } from '../dto/update-delivery.dto';
|
import { UpdateDeliveryDto } from '../dto/update-delivery.dto';
|
||||||
import { RestId } from 'src/common/decorators/rest-id.decorator';
|
import { ShopId } from 'src/common/decorators/rest-id.decorator';
|
||||||
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
|
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
|
||||||
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
|
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
|
||||||
import { Delivery } from '../entities/delivery.entity';
|
import { Delivery } from '../entities/delivery.entity';
|
||||||
@@ -24,14 +24,14 @@ import { Permissions } from 'src/common/decorators/permissions.decorator';
|
|||||||
@ApiTags('Delivery')
|
@ApiTags('Delivery')
|
||||||
@Controller()
|
@Controller()
|
||||||
export class DeliveryController {
|
export class DeliveryController {
|
||||||
constructor(private readonly deliveryService: DeliveryService) {}
|
constructor(private readonly deliveryService: DeliveryService) { }
|
||||||
|
|
||||||
@UseGuards(AuthGuard)
|
@UseGuards(AuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Get('public/delivery-methods/shop')
|
@Get('public/delivery-methods/shop')
|
||||||
@ApiOperation({ summary: 'Get shop delivery methods' })
|
@ApiOperation({ summary: 'Get shop delivery methods' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
findAllDeliveryMethods(@RestId() restId: string) {
|
findAllDeliveryMethods(@ShopId() restId: string) {
|
||||||
return this.deliveryService.findAllForRestaurantId(restId);
|
return this.deliveryService.findAllForRestaurantId(restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ export class DeliveryController {
|
|||||||
@Post('admin/delivery-methods/shop')
|
@Post('admin/delivery-methods/shop')
|
||||||
@ApiOperation({ summary: 'Create a delivery method for a shop' })
|
@ApiOperation({ summary: 'Create a delivery method for a shop' })
|
||||||
@ApiBody({ type: CreateDeliveryDto })
|
@ApiBody({ type: CreateDeliveryDto })
|
||||||
create(@Body() createDto: CreateDeliveryDto, @RestId() restId: string) {
|
create(@Body() createDto: CreateDeliveryDto, @ShopId() restId: string) {
|
||||||
return this.deliveryService.create(restId, createDto);
|
return this.deliveryService.create(restId, createDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ export class DeliveryController {
|
|||||||
@Permissions(Permission.MANAGE_DELIVERY)
|
@Permissions(Permission.MANAGE_DELIVERY)
|
||||||
@Get('admin/delivery-methods/shop')
|
@Get('admin/delivery-methods/shop')
|
||||||
@ApiOperation({ summary: 'Get the shop delivery methods' })
|
@ApiOperation({ summary: 'Get the shop delivery methods' })
|
||||||
findRestaurantDeliveryMethods(@RestId() restId: string) {
|
findRestaurantDeliveryMethods(@ShopId() restId: string) {
|
||||||
return this.deliveryService.findAllForRestaurantId(restId);
|
return this.deliveryService.findAllForRestaurantId(restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ export class DeliveryController {
|
|||||||
@Get('admin/delivery-methods/shop/:deliveryId')
|
@Get('admin/delivery-methods/shop/:deliveryId')
|
||||||
@ApiOperation({ summary: 'Get a shop delivery method by delivery ID' })
|
@ApiOperation({ summary: 'Get a shop delivery method by delivery ID' })
|
||||||
@ApiParam({ name: 'deliveryId', description: 'Delivery method ID' })
|
@ApiParam({ name: 'deliveryId', description: 'Delivery method ID' })
|
||||||
findOne(@Param('deliveryId') deliveryId: string, @RestId() restId: string) {
|
findOne(@Param('deliveryId') deliveryId: string, @ShopId() restId: string) {
|
||||||
return this.deliveryService.findOne(restId, deliveryId);
|
return this.deliveryService.findOne(restId, deliveryId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ export class DeliveryController {
|
|||||||
@ApiOperation({ summary: 'Update a shop delivery method' })
|
@ApiOperation({ summary: 'Update a shop delivery method' })
|
||||||
@ApiParam({ name: 'deliveryId', description: 'Delivery method ID' })
|
@ApiParam({ name: 'deliveryId', description: 'Delivery method ID' })
|
||||||
@ApiBody({ type: UpdateDeliveryDto })
|
@ApiBody({ type: UpdateDeliveryDto })
|
||||||
update(@Param('deliveryId') deliveryId: string, @Body() updateDto: UpdateDeliveryDto, @RestId() restId: string) {
|
update(@Param('deliveryId') deliveryId: string, @Body() updateDto: UpdateDeliveryDto, @ShopId() restId: string) {
|
||||||
return this.deliveryService.update(restId, deliveryId, updateDto);
|
return this.deliveryService.update(restId, deliveryId, updateDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ export class DeliveryController {
|
|||||||
@Delete('admin/delivery-methods/shop/:deliveryId')
|
@Delete('admin/delivery-methods/shop/:deliveryId')
|
||||||
@ApiOperation({ summary: 'Delete a shop delivery method' })
|
@ApiOperation({ summary: 'Delete a shop delivery method' })
|
||||||
@ApiParam({ name: 'deliveryId', description: 'Delivery method ID' })
|
@ApiParam({ name: 'deliveryId', description: 'Delivery method ID' })
|
||||||
remove(@Param('deliveryId') deliveryId: string, @RestId() restId: string) {
|
remove(@Param('deliveryId') deliveryId: string, @ShopId() restId: string) {
|
||||||
return this.deliveryService.remove(restId, deliveryId);
|
return this.deliveryService.remove(restId, deliveryId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export class Product extends BaseEntity {
|
|||||||
@Property({ type: 'json', nullable: true })
|
@Property({ type: 'json', nullable: true })
|
||||||
content?: string[];
|
content?: string[];
|
||||||
|
|
||||||
@Property({ type: 'decimal', precision: 10, scale: 2, nullable: true })
|
@Property({ type: 'decimal', precision: 10, scale: 0, nullable: true })
|
||||||
price?: number;
|
price?: number;
|
||||||
|
|
||||||
@Property({ type: 'int', nullable: true })
|
@Property({ type: 'int', nullable: true })
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export class NotificationsController {
|
|||||||
@ApiQuery({ name: 'status', required: false, enum: ['seen', 'unseen'], description: 'Filter by notification status' })
|
@ApiQuery({ name: 'status', required: false, enum: ['seen', 'unseen'], description: 'Filter by notification status' })
|
||||||
async getUserNotifications(
|
async getUserNotifications(
|
||||||
@UserId() userId: string,
|
@UserId() userId: string,
|
||||||
@RestId() restaurantId: string,
|
@ShopId() restaurantId: string,
|
||||||
@Query('limit') limit?: number,
|
@Query('limit') limit?: number,
|
||||||
@Query('cursor') cursor?: string,
|
@Query('cursor') cursor?: string,
|
||||||
@Query('status') status?: 'seen' | 'unseen',
|
@Query('status') status?: 'seen' | 'unseen',
|
||||||
@@ -57,7 +57,7 @@ export class NotificationsController {
|
|||||||
@Get('public/notifications/unseen-count')
|
@Get('public/notifications/unseen-count')
|
||||||
@ApiOperation({ summary: 'Get unseen notifications count for user' })
|
@ApiOperation({ summary: 'Get unseen notifications count for user' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
async getUserUnseenCount(@UserId() userId: string, @RestId() restaurantId: string) {
|
async getUserUnseenCount(@UserId() userId: string, @ShopId() restaurantId: string) {
|
||||||
const count = await this.notificationService.countUnseenByUserAndRestaurant(userId, restaurantId);
|
const count = await this.notificationService.countUnseenByUserAndRestaurant(userId, restaurantId);
|
||||||
return { count };
|
return { count };
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ export class NotificationsController {
|
|||||||
@Put('public/notifications/:id')
|
@Put('public/notifications/:id')
|
||||||
@ApiOperation({ summary: 'Read a notification ' })
|
@ApiOperation({ summary: 'Read a notification ' })
|
||||||
@ApiParam({ name: 'id', description: 'Notification ID' })
|
@ApiParam({ name: 'id', description: 'Notification ID' })
|
||||||
async readNotificationUser(@RestId() restaurantId: string, @Param('id') id: string, @UserId() userId: string) {
|
async readNotificationUser(@ShopId() restaurantId: string, @Param('id') id: string, @UserId() userId: string) {
|
||||||
await this.notificationService.readNotificationAsUser(id, userId, restaurantId);
|
await this.notificationService.readNotificationAsUser(id, userId, restaurantId);
|
||||||
return { message: NotificationMessage.READ_SUCCESS };
|
return { message: NotificationMessage.READ_SUCCESS };
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ export class NotificationsController {
|
|||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Put('public/notifications/read/all')
|
@Put('public/notifications/read/all')
|
||||||
@ApiOperation({ summary: 'Read all notification ' })
|
@ApiOperation({ summary: 'Read all notification ' })
|
||||||
async readAllNotificationUser(@RestId() restaurantId: string, @UserId() userId: string) {
|
async readAllNotificationUser(@ShopId() restaurantId: string, @UserId() userId: string) {
|
||||||
await this.notificationService.readAllNotifsAsUser(userId, restaurantId);
|
await this.notificationService.readAllNotifsAsUser(userId, restaurantId);
|
||||||
return { message: NotificationMessage.READ_SUCCESS };
|
return { message: NotificationMessage.READ_SUCCESS };
|
||||||
}
|
}
|
||||||
@@ -96,7 +96,7 @@ export class NotificationsController {
|
|||||||
@ApiQuery({ name: 'status', required: false, enum: ['seen', 'unseen'], description: 'Filter by notification status' })
|
@ApiQuery({ name: 'status', required: false, enum: ['seen', 'unseen'], description: 'Filter by notification status' })
|
||||||
async getAdminNotifications(
|
async getAdminNotifications(
|
||||||
@AdminId() adminId: string,
|
@AdminId() adminId: string,
|
||||||
@RestId() restaurantId: string,
|
@ShopId() restaurantId: string,
|
||||||
@Query('limit') limit?: number,
|
@Query('limit') limit?: number,
|
||||||
@Query('cursor') cursor?: string,
|
@Query('cursor') cursor?: string,
|
||||||
@Query('status') status?: 'seen' | 'unseen',
|
@Query('status') status?: 'seen' | 'unseen',
|
||||||
@@ -109,7 +109,7 @@ export class NotificationsController {
|
|||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Get('admin/notifications/unseen-count')
|
@Get('admin/notifications/unseen-count')
|
||||||
@ApiOperation({ summary: 'Get unseen notifications count for admin' })
|
@ApiOperation({ summary: 'Get unseen notifications count for admin' })
|
||||||
async getAdminUnseenCount(@AdminId() adminId: string, @RestId() restaurantId: string) {
|
async getAdminUnseenCount(@AdminId() adminId: string, @ShopId() restaurantId: string) {
|
||||||
const count = await this.notificationService.countUnseenByRestaurant(adminId, restaurantId);
|
const count = await this.notificationService.countUnseenByRestaurant(adminId, restaurantId);
|
||||||
return { count };
|
return { count };
|
||||||
}
|
}
|
||||||
@@ -119,7 +119,7 @@ export class NotificationsController {
|
|||||||
@Put('admin/notifications/:id')
|
@Put('admin/notifications/:id')
|
||||||
@ApiOperation({ summary: 'Read a notification ' })
|
@ApiOperation({ summary: 'Read a notification ' })
|
||||||
@ApiParam({ name: 'id', description: 'Notification ID' })
|
@ApiParam({ name: 'id', description: 'Notification ID' })
|
||||||
async readNotificationAdmin(@RestId() restaurantId: string, @AdminId() adminId: string, @Param('id') id: string) {
|
async readNotificationAdmin(@ShopId() restaurantId: string, @AdminId() adminId: string, @Param('id') id: string) {
|
||||||
await this.notificationService.readNotificationAdmin(id, adminId, restaurantId);
|
await this.notificationService.readNotificationAdmin(id, adminId, restaurantId);
|
||||||
return { message: NotificationMessage.READ_SUCCESS };
|
return { message: NotificationMessage.READ_SUCCESS };
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ export class NotificationsController {
|
|||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Put('admin/notifications/read/all')
|
@Put('admin/notifications/read/all')
|
||||||
@ApiOperation({ summary: 'Read all notification ' })
|
@ApiOperation({ summary: 'Read all notification ' })
|
||||||
async readAllNotificationAdmin(@RestId() restaurantId: string, @AdminId() adminId: string, @Param('id') id: string) {
|
async readAllNotificationAdmin(@ShopId() restaurantId: string, @AdminId() adminId: string, @Param('id') id: string) {
|
||||||
await this.notificationService.readAllNotifsAsAdmin(adminId, restaurantId);
|
await this.notificationService.readAllNotifsAsAdmin(adminId, restaurantId);
|
||||||
return { message: NotificationMessage.READ_SUCCESS };
|
return { message: NotificationMessage.READ_SUCCESS };
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ export class NotificationsController {
|
|||||||
@Permissions(Permission.MANAGE_SETTINGS)
|
@Permissions(Permission.MANAGE_SETTINGS)
|
||||||
@Get('admin/notification-preferences')
|
@Get('admin/notification-preferences')
|
||||||
@ApiOperation({ summary: 'Get all notification preferences for a shop' })
|
@ApiOperation({ summary: 'Get all notification preferences for a shop' })
|
||||||
async getPreferences(@RestId() restaurantId: string) {
|
async getPreferences(@ShopId() restaurantId: string) {
|
||||||
return this.preferenceService.findByRestaurant(restaurantId);
|
return this.preferenceService.findByRestaurant(restaurantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ export class NotificationsController {
|
|||||||
@ApiOperation({ summary: 'Update notification channels' })
|
@ApiOperation({ summary: 'Update notification channels' })
|
||||||
@ApiParam({ name: 'id', description: 'Notification preference ID' })
|
@ApiParam({ name: 'id', description: 'Notification preference ID' })
|
||||||
async updatePreference(
|
async updatePreference(
|
||||||
@RestId() restaurantId: string,
|
@ShopId() restaurantId: string,
|
||||||
@Param('id') preferenceId: string,
|
@Param('id') preferenceId: string,
|
||||||
@Body() dto: UpdatePreferenceDto,
|
@Body() dto: UpdatePreferenceDto,
|
||||||
) {
|
) {
|
||||||
@@ -162,7 +162,7 @@ export class NotificationsController {
|
|||||||
@Post('admin/notification-preferences')
|
@Post('admin/notification-preferences')
|
||||||
@ApiOperation({ summary: 'Create notification preference' })
|
@ApiOperation({ summary: 'Create notification preference' })
|
||||||
async createPreference(
|
async createPreference(
|
||||||
@RestId() restaurantId: string,
|
@ShopId() restaurantId: string,
|
||||||
@Body() dto: CreatePreferenceDto,
|
@Body() dto: CreatePreferenceDto,
|
||||||
) {
|
) {
|
||||||
return this.preferenceService.create(restaurantId, dto);
|
return this.preferenceService.create(restaurantId, dto);
|
||||||
@@ -172,7 +172,7 @@ export class NotificationsController {
|
|||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Get('admin/notifications/sms-usage')
|
@Get('admin/notifications/sms-usage')
|
||||||
@ApiOperation({ summary: 'Get SMS usage for my shop' })
|
@ApiOperation({ summary: 'Get SMS usage for my shop' })
|
||||||
async getRestaurantSmsUsage(@RestId() restaurantId: string) {
|
async getRestaurantSmsUsage(@ShopId() restaurantId: string) {
|
||||||
const smsCount = await this.notificationService.getSmsCountByRestaurantId(restaurantId);
|
const smsCount = await this.notificationService.getSmsCountByRestaurantId(restaurantId);
|
||||||
return { smsCount };
|
return { smsCount };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiHeader, ApiBody } fr
|
|||||||
import { OrdersService } from '../providers/orders.service';
|
import { OrdersService } from '../providers/orders.service';
|
||||||
import { AuthGuard } from '../../../auth/guards/auth.guard';
|
import { AuthGuard } from '../../../auth/guards/auth.guard';
|
||||||
import { UserId } from '../../../../common/decorators/user-id.decorator';
|
import { UserId } from '../../../../common/decorators/user-id.decorator';
|
||||||
import { RestId } from 'src/common/decorators/rest-id.decorator';
|
import { ShopId } from 'src/common/decorators/rest-id.decorator';
|
||||||
import { AdminAuthGuard } from '../../../auth/guards/adminAuth.guard';
|
import { AdminAuthGuard } from '../../../auth/guards/adminAuth.guard';
|
||||||
import { FindOrdersDto } from '../dto/find-orders.dto';
|
import { FindOrdersDto } from '../dto/find-orders.dto';
|
||||||
import { OrderStatus } from '../interface/order.interface';
|
import { OrderStatus } from '../interface/order.interface';
|
||||||
@@ -22,7 +22,7 @@ export class OrdersController {
|
|||||||
@Post('public/checkout')
|
@Post('public/checkout')
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiOperation({ summary: 'Checkout : create order and payment record' })
|
@ApiOperation({ summary: 'Checkout : create order and payment record' })
|
||||||
checkout(@UserId() userId: string, @RestId() restaurantId: string) {
|
checkout(@UserId() userId: string, @ShopId() restaurantId: string) {
|
||||||
return this.ordersService.checkout(userId, restaurantId);
|
return this.ordersService.checkout(userId, restaurantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ export class OrdersController {
|
|||||||
@Get('public/orders')
|
@Get('public/orders')
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiOperation({ summary: 'Get all orders with pagination and filters' })
|
@ApiOperation({ summary: 'Get all orders with pagination and filters' })
|
||||||
findAll(@RestId() restId: string, @Query() dto: FindOrdersDto, @UserId() userId: string) {
|
findAll(@ShopId() restId: string, @Query() dto: FindOrdersDto, @UserId() userId: string) {
|
||||||
return this.ordersService.findAllForUser(restId, dto, userId);
|
return this.ordersService.findAllForUser(restId, dto, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ export class OrdersController {
|
|||||||
@ApiParam({ name: 'orderId', description: 'Order ID' })
|
@ApiParam({ name: 'orderId', description: 'Order ID' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@Get('public/orders/:orderId')
|
@Get('public/orders/:orderId')
|
||||||
findOne(@Param('orderId') orderId: string, @RestId() restId: string) {
|
findOne(@Param('orderId') orderId: string, @ShopId() restId: string) {
|
||||||
return this.ordersService.findOne(orderId, restId);
|
return this.ordersService.findOne(orderId, restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ export class OrdersController {
|
|||||||
@Body() dto: UpdateOrderStatusDto,
|
@Body() dto: UpdateOrderStatusDto,
|
||||||
@Param('id') orderId: string,
|
@Param('id') orderId: string,
|
||||||
@Param('status') status: OrderStatus,
|
@Param('status') status: OrderStatus,
|
||||||
@RestId() restId: string,
|
@ShopId() restId: string,
|
||||||
) {
|
) {
|
||||||
return this.ordersService.changeOrderStatus(orderId, restId, status, 'user', dto?.desc);
|
return this.ordersService.changeOrderStatus(orderId, restId, status, 'user', dto?.desc);
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ export class OrdersController {
|
|||||||
@Permissions(Permission.MANAGE_ORDERS)
|
@Permissions(Permission.MANAGE_ORDERS)
|
||||||
@Get('admin/orders')
|
@Get('admin/orders')
|
||||||
@ApiOperation({ summary: 'Get all orders with pagination and filters' })
|
@ApiOperation({ summary: 'Get all orders with pagination and filters' })
|
||||||
findAllAdmin(@RestId() restId: string, @Query() dto: FindOrdersDto) {
|
findAllAdmin(@ShopId() restId: string, @Query() dto: FindOrdersDto) {
|
||||||
return this.ordersService.findAllForAdmin(restId, dto);
|
return this.ordersService.findAllForAdmin(restId, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ export class OrdersController {
|
|||||||
@ApiOperation({ summary: 'Get an order By id for User' })
|
@ApiOperation({ summary: 'Get an order By id for User' })
|
||||||
@ApiParam({ name: 'orderId', description: 'Order ID' })
|
@ApiParam({ name: 'orderId', description: 'Order ID' })
|
||||||
@Get('admin/orders/:orderId')
|
@Get('admin/orders/:orderId')
|
||||||
findOneAsAdmin(@Param('orderId') orderId: string, @RestId() restId: string) {
|
findOneAsAdmin(@Param('orderId') orderId: string, @ShopId() restId: string) {
|
||||||
return this.ordersService.findOne(orderId, restId);
|
return this.ordersService.findOne(orderId, restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ export class OrdersController {
|
|||||||
@Param('orderId') orderId: string,
|
@Param('orderId') orderId: string,
|
||||||
@Body() dto: UpdateOrderStatusDto,
|
@Body() dto: UpdateOrderStatusDto,
|
||||||
@Param('status') status: OrderStatus,
|
@Param('status') status: OrderStatus,
|
||||||
@RestId() restId: string,
|
@ShopId() restId: string,
|
||||||
) {
|
) {
|
||||||
return this.ordersService.changeOrderStatus(orderId, restId, status, 'admin', dto?.desc);
|
return this.ordersService.changeOrderStatus(orderId, restId, status, 'admin', dto?.desc);
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ export class OrdersController {
|
|||||||
@Permissions(Permission.VIEW_REPORTS)
|
@Permissions(Permission.VIEW_REPORTS)
|
||||||
@ApiOperation({ summary: 'Get Stats for report page' })
|
@ApiOperation({ summary: 'Get Stats for report page' })
|
||||||
@Get('admin/orders/stats')
|
@Get('admin/orders/stats')
|
||||||
findStats(@RestId() restId: string) {
|
findStats(@ShopId() restId: string) {
|
||||||
return this.ordersService.getStats(restId);
|
return this.ordersService.getStats(restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ export class OrdersController {
|
|||||||
@ApiOperation({ summary: 'Get product sales pie chart data for last month' })
|
@ApiOperation({ summary: 'Get product sales pie chart data for last month' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@Get('admin/orders/product-sales-pie-chart')
|
@Get('admin/orders/product-sales-pie-chart')
|
||||||
getFoodSalesPieChart(@RestId() restId: string) {
|
getFoodSalesPieChart(@ShopId() restId: string) {
|
||||||
return this.ordersService.getFoodSalesPieChart(restId);
|
return this.ordersService.getFoodSalesPieChart(restId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Controller, Get, Post, Body, UseGuards, Res, Req, Patch, Param } from '
|
|||||||
import { PagerService } from '../providers/pager.service';
|
import { PagerService } from '../providers/pager.service';
|
||||||
import { CreatePagerDto } from '../dto/create-pager.dto';
|
import { CreatePagerDto } from '../dto/create-pager.dto';
|
||||||
import { OptionalAuthGuard } from '../../../auth/guards/optinalAuth.guard';
|
import { OptionalAuthGuard } from '../../../auth/guards/optinalAuth.guard';
|
||||||
import { RestId } from 'src/common/decorators/rest-id.decorator';
|
import { ShopId } from 'src/common/decorators/rest-id.decorator';
|
||||||
import { UserId } from 'src/common/decorators/user-id.decorator';
|
import { UserId } from 'src/common/decorators/user-id.decorator';
|
||||||
import { RestSlug } from 'src/common/decorators/rest-slug.decorator';
|
import { RestSlug } from 'src/common/decorators/rest-slug.decorator';
|
||||||
import { ApiTags, ApiOperation, ApiBody, ApiHeader, ApiBearerAuth, ApiParam } from '@nestjs/swagger';
|
import { ApiTags, ApiOperation, ApiBody, ApiHeader, ApiBearerAuth, ApiParam } from '@nestjs/swagger';
|
||||||
@@ -31,7 +31,7 @@ export class PagerController {
|
|||||||
@Req() request: FastifyRequest,
|
@Req() request: FastifyRequest,
|
||||||
@Res() reply: FastifyReply,
|
@Res() reply: FastifyReply,
|
||||||
@RestSlug() slug: string,
|
@RestSlug() slug: string,
|
||||||
@RestId() restId?: string,
|
@ShopId() restId?: string,
|
||||||
@UserId() userId?: string,
|
@UserId() userId?: string,
|
||||||
) {
|
) {
|
||||||
// Convert empty strings to undefined for cleaner validation
|
// Convert empty strings to undefined for cleaner validation
|
||||||
@@ -79,7 +79,7 @@ export class PagerController {
|
|||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Get('admin/pager')
|
@Get('admin/pager')
|
||||||
@ApiOperation({ summary: 'Get all pager requests for the shop' })
|
@ApiOperation({ summary: 'Get all pager requests for the shop' })
|
||||||
async findAllAdmin(@RestId() restId: string) {
|
async findAllAdmin(@ShopId() restId: string) {
|
||||||
return this.pagerService.findAllByRestaurantId(restId);
|
return this.pagerService.findAllByRestaurantId(restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ export class PagerController {
|
|||||||
@ApiBody({ type: UpdatePagerStatusDto })
|
@ApiBody({ type: UpdatePagerStatusDto })
|
||||||
async updateStatus(
|
async updateStatus(
|
||||||
@Param('pagerId') pagerId: string,
|
@Param('pagerId') pagerId: string,
|
||||||
@RestId() restId: string,
|
@ShopId() restId: string,
|
||||||
@AdminId() adminId: string,
|
@AdminId() adminId: string,
|
||||||
@Body() dto: UpdatePagerStatusDto,
|
@Body() dto: UpdatePagerStatusDto,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export class PaymentsController {
|
|||||||
@ApiOperation({ summary: 'Get the shop payment methods' })
|
@ApiOperation({ summary: 'Get the shop payment methods' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiNotFoundResponse({ description: 'Shop payment methods not found' })
|
@ApiNotFoundResponse({ description: 'Shop payment methods not found' })
|
||||||
getTheRestaurantPaymentMethods(@RestId() restId: string) {
|
getTheRestaurantPaymentMethods(@ShopId() restId: string) {
|
||||||
return this.paymentMethodService.findByRestaurant(restId);
|
return this.paymentMethodService.findByRestaurant(restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ export class PaymentsController {
|
|||||||
@Get('public/payments')
|
@Get('public/payments')
|
||||||
@ApiOperation({ summary: 'Get all the shop payments for user' })
|
@ApiOperation({ summary: 'Get all the shop payments for user' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
findAllByRestaurant(@UserId() userId: string, @RestId() restId: string) {
|
findAllByRestaurant(@UserId() userId: string, @ShopId() restId: string) {
|
||||||
return this.paymentsService.findAllPaymentsByRestaurantId(restId, userId);
|
return this.paymentsService.findAllPaymentsByRestaurantId(restId, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ export class PaymentsController {
|
|||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Get('admin/payments/methods')
|
@Get('admin/payments/methods')
|
||||||
@ApiOperation({ summary: 'Get shop all payment methods' })
|
@ApiOperation({ summary: 'Get shop all payment methods' })
|
||||||
findByRestaurant(@RestId() restId: string) {
|
findByRestaurant(@ShopId() restId: string) {
|
||||||
return this.paymentMethodService.findByRestaurant(restId);
|
return this.paymentMethodService.findByRestaurant(restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ export class PaymentsController {
|
|||||||
@Post('admin/payments/methods')
|
@Post('admin/payments/methods')
|
||||||
@ApiOperation({ summary: 'Create a new shop payment method' })
|
@ApiOperation({ summary: 'Create a new shop payment method' })
|
||||||
@ApiBody({ type: CreatePaymentMethodDto })
|
@ApiBody({ type: CreatePaymentMethodDto })
|
||||||
createRestaurantPaymentMethod(@RestId() restId: string, @Body() createPaymentMethodDto: CreatePaymentMethodDto) {
|
createRestaurantPaymentMethod(@ShopId() restId: string, @Body() createPaymentMethodDto: CreatePaymentMethodDto) {
|
||||||
return this.paymentMethodService.create(restId, createPaymentMethodDto);
|
return this.paymentMethodService.create(restId, createPaymentMethodDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ export class PaymentsController {
|
|||||||
@Get('admin/payments/chart')
|
@Get('admin/payments/chart')
|
||||||
@ApiOperation({ summary: 'Get payment chart data with date and period filters' })
|
@ApiOperation({ summary: 'Get payment chart data with date and period filters' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
getPaymentChart(@Query() query: PaymentChartDto, @RestId() restId: string) {
|
getPaymentChart(@Query() query: PaymentChartDto, @ShopId() restId: string) {
|
||||||
return this.paymentsService.getChartData(query, restId);
|
return this.paymentsService.getChartData(query, restId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export class CategoryController {
|
|||||||
@UseGuards(AdminAuthGuard)
|
@UseGuards(AdminAuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Post('admin/categories')
|
@Post('admin/categories')
|
||||||
create(@Body() dto: CreateCategoryDto, @RestId() restId: string) {
|
create(@Body() dto: CreateCategoryDto, @ShopId() restId: string) {
|
||||||
return this.categoryService.create(restId, dto);
|
return this.categoryService.create(restId, dto);
|
||||||
}
|
}
|
||||||
@Permissions(Permission.MANAGE_CATEGORIES)
|
@Permissions(Permission.MANAGE_CATEGORIES)
|
||||||
@@ -50,7 +50,7 @@ export class CategoryController {
|
|||||||
@UseGuards(AdminAuthGuard)
|
@UseGuards(AdminAuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Get('admin/categories')
|
@Get('admin/categories')
|
||||||
findAll(@RestId() restId: string) {
|
findAll(@ShopId() restId: string) {
|
||||||
return this.categoryService.findAllByRestaurantId(restId);
|
return this.categoryService.findAllByRestaurantId(restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ export class CategoryController {
|
|||||||
@Get('admin/categories/:id')
|
@Get('admin/categories/:id')
|
||||||
@ApiOperation({ summary: 'Get category' })
|
@ApiOperation({ summary: 'Get category' })
|
||||||
@ApiParam({ name: 'id', required: true, type: String })
|
@ApiParam({ name: 'id', required: true, type: String })
|
||||||
findOne(@Param('id') id: string, @RestId() restId: string) {
|
findOne(@Param('id') id: string, @ShopId() restId: string) {
|
||||||
return this.categoryService.findOne(restId, id);
|
return this.categoryService.findOne(restId, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ export class CategoryController {
|
|||||||
@ApiOperation({ summary: 'Update category' })
|
@ApiOperation({ summary: 'Update category' })
|
||||||
@ApiParam({ name: 'id' })
|
@ApiParam({ name: 'id' })
|
||||||
@ApiBody({ type: UpdateCategoryDto })
|
@ApiBody({ type: UpdateCategoryDto })
|
||||||
update(@Param('id') id: string, @Body() dto: UpdateCategoryDto, @RestId() restId: string) {
|
update(@Param('id') id: string, @Body() dto: UpdateCategoryDto, @ShopId() restId: string) {
|
||||||
return this.categoryService.update(restId, id, dto);
|
return this.categoryService.update(restId, id, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ export class CategoryController {
|
|||||||
@ApiOperation({ summary: 'Delete category' })
|
@ApiOperation({ summary: 'Delete category' })
|
||||||
@ApiParam({ name: 'id' })
|
@ApiParam({ name: 'id' })
|
||||||
@ApiOkResponse({ description: 'Deleted' })
|
@ApiOkResponse({ description: 'Deleted' })
|
||||||
remove(@Param('id') id: string, @RestId() restId: string) {
|
remove(@Param('id') id: string, @ShopId() restId: string) {
|
||||||
return this.categoryService.remove(restId, id);
|
return this.categoryService.remove(restId, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common';
|
import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common';
|
||||||
import { FoodService } from '../providers/product.service';
|
import { ProductService } from '../providers/product.service';
|
||||||
import { CreateFoodDto } from '../dto/create-product.dto';
|
import { CreateProductDto } from '../dto/create-product.dto';
|
||||||
import { UpdateFoodDto } from '../dto/update-product.dto';
|
import { UpdateFoodDto } from '../dto/update-product.dto';
|
||||||
import { FindFoodsDto } from ../../../products.dto';
|
import { FindProductsDto } from '../dto/find-products.dto';
|
||||||
import {
|
import {
|
||||||
ApiTags,
|
ApiTags,
|
||||||
ApiOperation,
|
ApiOperation,
|
||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
ApiHeader,
|
ApiHeader,
|
||||||
} from '@nestjs/swagger';
|
} from '@nestjs/swagger';
|
||||||
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
|
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
|
||||||
import { RestId, UserId } from 'src/common/decorators';
|
import { ShopId, UserId } from 'src/common/decorators';
|
||||||
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
|
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
|
||||||
import { OptionalAuthGuard } from 'src/modules/auth/guards/optinalAuth.guard';
|
import { OptionalAuthGuard } from 'src/modules/auth/guards/optinalAuth.guard';
|
||||||
import { API_HEADER_SLUG } from 'src/common/constants';
|
import { API_HEADER_SLUG } from 'src/common/constants';
|
||||||
@@ -23,35 +23,34 @@ import { Permissions } from 'src/common/decorators/permissions.decorator';
|
|||||||
@ApiTags('products')
|
@ApiTags('products')
|
||||||
@Controller()
|
@Controller()
|
||||||
export class FoodController {
|
export class FoodController {
|
||||||
constructor(private readonly foodsService: FoodService) { }
|
constructor(private readonly productService: ProductService) { }
|
||||||
|
|
||||||
@Get('public/products/shop/:slug')
|
@Get('public/products/shop/:slug')
|
||||||
@ApiOperation({ summary: 'Get all products by shop slug' })
|
@ApiOperation({ summary: 'Get all products by shop slug' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiParam({ name: 'slug', required: true, description: 'Shop Slug' })
|
@ApiParam({ name: 'slug', required: true, description: 'Shop Slug' })
|
||||||
findAllByRestaurant(@Param('slug') slug: string) {
|
findAllByRestaurant(@Param('slug') slug: string) {
|
||||||
return this.foodsService.findByWeekDateAndMealType(slug);
|
return this.productService.findByShop(slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('public/products/:foodId')
|
@Get('public/products/:id')
|
||||||
@UseGuards(OptionalAuthGuard)
|
@UseGuards(OptionalAuthGuard)
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOperation({ summary: 'Get a product by id' })
|
@ApiOperation({ summary: 'Get a product by id' })
|
||||||
@ApiParam({ name: 'foodId', required: true })
|
findPublicFoodById(@Param('id') productId: string, @UserId() userId?: string): Promise<any> {
|
||||||
findPublicFoodById(@Param('foodId') foodId: string, @UserId() userId?: string): Promise<any> {
|
const a = this.productService.findPublicById(productId, userId);
|
||||||
const a = this.foodsService.findPublicById(foodId, userId);
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('public/products/favorite/:foodId')
|
@Post('public/products/:id/favorite')
|
||||||
@UseGuards(AuthGuard)
|
@UseGuards(AuthGuard)
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOperation({ summary: 'toggle a product as favorite' })
|
@ApiOperation({ summary: 'toggle a product as favorite' })
|
||||||
@ApiParam({ name: 'foodId', required: true })
|
@ApiParam({ name: 'productId', required: true })
|
||||||
setAsFavorute(@Param('foodId') foodId: string, @UserId() userId: string) {
|
setAsFavorute(@Param('productId') productId: string, @UserId() userId: string) {
|
||||||
return this.foodsService.toggleFavorite(userId, foodId);
|
return this.productService.toggleFavorite(userId, productId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('public/products/favorite')
|
@Get('public/products/favorite')
|
||||||
@@ -59,8 +58,8 @@ export class FoodController {
|
|||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOperation({ summary: 'get my favorites' })
|
@ApiOperation({ summary: 'get my favorites' })
|
||||||
getMyFavorites(@UserId() userId: string, @RestId() restId: string) {
|
getMyFavorites(@UserId() userId: string, @ShopId() restId: string) {
|
||||||
return this.foodsService.getMyFavorites(userId, restId);
|
return this.productService.getMyFavorites(userId, restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------- Admin ---------------------------------- */
|
/* ---------------------------------- Admin ---------------------------------- */
|
||||||
@@ -69,9 +68,8 @@ export class FoodController {
|
|||||||
@Permissions(Permission.MANAGE_FOODS)
|
@Permissions(Permission.MANAGE_FOODS)
|
||||||
@Post('admin/products')
|
@Post('admin/products')
|
||||||
@ApiOperation({ summary: 'Create a new product' })
|
@ApiOperation({ summary: 'Create a new product' })
|
||||||
@ApiBody({ type: CreateFoodDto })
|
create(@Body() createFoodDto: CreateProductDto, @ShopId() restId: string) {
|
||||||
create(@Body() createFoodDto: CreateFoodDto, @RestId() restId: string) {
|
return this.productService.create(restId, createFoodDto);
|
||||||
return this.foodsService.create(restId, createFoodDto);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseGuards(AdminAuthGuard)
|
@UseGuards(AdminAuthGuard)
|
||||||
@@ -86,8 +84,8 @@ export class FoodController {
|
|||||||
@ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
|
@ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
|
||||||
@ApiQuery({ name: 'categoryId', required: false, type: String })
|
@ApiQuery({ name: 'categoryId', required: false, type: String })
|
||||||
@ApiQuery({ name: 'isActive', required: false, type: Boolean })
|
@ApiQuery({ name: 'isActive', required: false, type: Boolean })
|
||||||
async findAll(@Query() dto: FindFoodsDto, @RestId() restId: string) {
|
async findAll(@Query() dto: FindProductsDto, @ShopId() restId: string) {
|
||||||
const result = await this.foodsService.findAll(restId, dto);
|
const result = await this.productService.findAll(restId, dto);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,8 +95,8 @@ export class FoodController {
|
|||||||
@Get('admin/products/:id')
|
@Get('admin/products/:id')
|
||||||
@ApiOperation({ summary: 'Get a product by id' })
|
@ApiOperation({ summary: 'Get a product by id' })
|
||||||
@ApiParam({ name: 'id', required: true })
|
@ApiParam({ name: 'id', required: true })
|
||||||
findById(@Param('id') id: string, @RestId() restId: string) {
|
findById(@Param('id') id: string, @ShopId() restId: string) {
|
||||||
return this.foodsService.findAdminById(restId, id);
|
return this.productService.findAdminById(restId, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseGuards(AdminAuthGuard)
|
@UseGuards(AdminAuthGuard)
|
||||||
@@ -108,16 +106,15 @@ export class FoodController {
|
|||||||
@ApiOperation({ summary: 'Update a product' })
|
@ApiOperation({ summary: 'Update a product' })
|
||||||
@ApiParam({ name: 'id', required: true })
|
@ApiParam({ name: 'id', required: true })
|
||||||
@ApiBody({ type: UpdateFoodDto })
|
@ApiBody({ type: UpdateFoodDto })
|
||||||
update(@Param('id') id: string, @Body() updateFoodDto: UpdateFoodDto, @RestId() restId: string) {
|
update(@Param('id') id: string, @Body() updateFoodDto: UpdateFoodDto, @ShopId() restId: string) {
|
||||||
return this.foodsService.update(restId, id, updateFoodDto);
|
return this.productService.update(restId, id, updateFoodDto);
|
||||||
}
|
}
|
||||||
@UseGuards(AdminAuthGuard)
|
@UseGuards(AdminAuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@Permissions(Permission.MANAGE_FOODS)
|
@Permissions(Permission.MANAGE_FOODS)
|
||||||
@Delete('admin/products/:id')
|
@Delete('admin/products/:id')
|
||||||
@ApiOperation({ summary: 'Delete (soft) a product' })
|
@ApiOperation({ summary: 'Delete (soft) a product' })
|
||||||
@ApiParam({ name: 'id', required: true })
|
remove(@Param('id') id: string, @ShopId() restId: string) {
|
||||||
remove(@Param('id') id: string, @RestId() restId: string) {
|
return this.productService.remove(restId, id);
|
||||||
return this.foodsService.remove(restId, id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,25 @@ import {
|
|||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class CreateFoodDto {
|
export class CreateVariantDto {
|
||||||
|
@IsString()
|
||||||
|
@ApiProperty()
|
||||||
|
id: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@ApiProperty()
|
||||||
|
value: string
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@ApiProperty()
|
||||||
|
price: number
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@ApiProperty()
|
||||||
|
stock: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateProductDto {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsString()
|
@IsString()
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@@ -25,16 +43,27 @@ export class CreateFoodDto {
|
|||||||
@ApiPropertyOptional({ example: 'قرمه سبزی' })
|
@ApiPropertyOptional({ example: 'قرمه سبزی' })
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@ApiPropertyOptional({ example: 'مثلا رنگ ،سایز' })
|
||||||
|
attribute?: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
type: CreateVariantDto,
|
||||||
|
example: [{
|
||||||
|
value: 'قرمز',
|
||||||
|
price: 100000,
|
||||||
|
stock: 20
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
variants: CreateVariantDto[]
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
@ApiPropertyOptional({ example: 'توضیحات غذا' })
|
@ApiPropertyOptional({ example: 'توضیحات غذا' })
|
||||||
desc?: string;
|
desc?: string;
|
||||||
|
|
||||||
@IsOptional()
|
|
||||||
@IsArray()
|
|
||||||
@IsString({ each: true })
|
|
||||||
@ApiPropertyOptional({ type: [String] })
|
|
||||||
content?: string[];
|
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@@ -67,7 +96,7 @@ export class CreateFoodDto {
|
|||||||
@Min(0)
|
@Min(0)
|
||||||
@Type(() => Number)
|
@Type(() => Number)
|
||||||
@ApiProperty({ example: 50 })
|
@ApiProperty({ example: 50 })
|
||||||
dailyStock: number;
|
stock: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { IsOptional, IsNumber, IsString, IsIn, IsBoolean } from 'class-validator
|
|||||||
import { ApiPropertyOptional } from '@nestjs/swagger';
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
|
|
||||||
export class FindFoodsDto {
|
export class FindProductsDto {
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@Type(() => Number)
|
@Type(() => Number)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { PartialType } from '@nestjs/swagger';
|
import { PartialType } from '@nestjs/swagger';
|
||||||
import { CreateFoodDto } from './create-product.dto';
|
import { CreateProductDto } from './create-product.dto';
|
||||||
|
|
||||||
export class UpdateFoodDto extends PartialType(CreateFoodDto) {}
|
export class UpdateFoodDto extends PartialType(CreateProductDto) { }
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Entity, Index, Property, Collection, OneToMany, ManyToOne } from '@mikro-orm/core';
|
import { Entity, Index, Property, Collection, OneToMany, ManyToOne } from '@mikro-orm/core';
|
||||||
import { Product } from './product.entity';
|
import { Product } from './product.entity';
|
||||||
import { BaseEntity } from '../../../../common/entities/base.entity';
|
import { BaseEntity } from '../../../../common/entities/base.entity';
|
||||||
import { Shop } from ../../../shops/entities/shop.entity';
|
import { Shop } from '../../../shops/entities/shop.entity';
|
||||||
|
|
||||||
@Entity({ tableName: 'categories' })
|
@Entity({ tableName: 'categories' })
|
||||||
@Index({ properties: ['shop', 'isActive'] })
|
@Index({ properties: ['shop', 'isActive'] })
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { Cascade, Collection, Entity, Index, ManyToOne, OneToMany, Property, OneToOne } from '@mikro-orm/core';
|
import { Cascade, Collection, Entity, Index, ManyToOne, OneToMany, Property, OneToOne } from '@mikro-orm/core';
|
||||||
import { Category } from './category.entity';
|
import { Category } from './category.entity';
|
||||||
import { BaseEntity } from '../../../../common/entities/base.entity';
|
import { BaseEntity } from '../../../common/entities/base.entity';
|
||||||
import { Shop } from '../../../../modules/shops/entities/shop.entity';
|
import { Shop } from '../../../modules/shops/entities/shop.entity';
|
||||||
import { Review } from 'src/modules/review/entities/review.entity';
|
import { Review } from 'src/modules/review/entities/review.entity';
|
||||||
import { Favorite } from './favorite.entity';
|
import { Favorite } from './favorite.entity';
|
||||||
|
import { Variant } from './variant.entity';
|
||||||
|
|
||||||
@Entity({ tableName: 'products' })
|
@Entity({ tableName: 'products' })
|
||||||
@Index({ properties: ['shop', 'isActive'] })
|
@Index({ properties: ['shop', 'isActive'] })
|
||||||
@@ -19,6 +20,11 @@ export class Product extends BaseEntity {
|
|||||||
@OneToMany(() => Review, review => review.product, { cascade: [Cascade.ALL], orphanRemoval: true })
|
@OneToMany(() => Review, review => review.product, { cascade: [Cascade.ALL], orphanRemoval: true })
|
||||||
reviews = new Collection<Review>(this);
|
reviews = new Collection<Review>(this);
|
||||||
|
|
||||||
|
@OneToMany(() => Variant, (variant) => variant.product, { cascade: [Cascade.ALL], orphanRemoval: true })
|
||||||
|
variants = new Collection<Variant>(this)
|
||||||
|
|
||||||
|
@Property({ type: 'string', nullable: true })
|
||||||
|
attribute?: string
|
||||||
|
|
||||||
@OneToMany(() => Favorite, favorite => favorite.product)
|
@OneToMany(() => Favorite, favorite => favorite.product)
|
||||||
favorites = new Collection<Favorite>(this);
|
favorites = new Collection<Favorite>(this);
|
||||||
@@ -29,12 +35,6 @@ export class Product extends BaseEntity {
|
|||||||
@Property({ type: 'text', nullable: true })
|
@Property({ type: 'text', nullable: true })
|
||||||
desc?: string;
|
desc?: string;
|
||||||
|
|
||||||
@Property({ type: 'json', nullable: true })
|
|
||||||
content?: string[];
|
|
||||||
|
|
||||||
@Property({ type: 'decimal', precision: 10, scale: 2, nullable: true })
|
|
||||||
price?: number;
|
|
||||||
|
|
||||||
@Property({ type: 'int', nullable: true })
|
@Property({ type: 'int', nullable: true })
|
||||||
order?: number;
|
order?: number;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { Entity, Index, Property, ManyToOne, ManyToMany, Collection } from '@mikro-orm/core';
|
||||||
|
import { Product } from './product.entity';
|
||||||
|
import { BaseEntity } from '../../../../common/entities/base.entity';
|
||||||
|
|
||||||
|
@Entity({ tableName: 'variants' })
|
||||||
|
@Index({ properties: ['product', 'isActive'] })
|
||||||
|
export class Variant extends BaseEntity {
|
||||||
|
@ManyToOne(() => Product)
|
||||||
|
product!: Product;
|
||||||
|
|
||||||
|
@Property({ type: 'string' })
|
||||||
|
value: string
|
||||||
|
|
||||||
|
@Property({ type: 'decimal', precision: 10, scale: 0, nullable: true })
|
||||||
|
price?: number;
|
||||||
|
|
||||||
|
@Property({ type: 'int', default: 0 })
|
||||||
|
stock: number = 0;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,32 +1,32 @@
|
|||||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
|
||||||
import { CreateFoodDto } from '../dto/create-product.dto';
|
import { CreateProductDto } from '../dto/create-product.dto';
|
||||||
import { FindFoodsDto } from ../../..products.dto';
|
import { FindProductsDto } from '../dto/find-products.dto';
|
||||||
import { FoodRepository } from '../repositories/product.repository';
|
import { ProductRepository } from '../repositories/product.repository';
|
||||||
import { CategoryRepository } from '../repositories/category.repository';
|
import { CategoryRepository } from '../repositories/category.repository';
|
||||||
import { EntityManager } from '@mikro-orm/postgresql';
|
import { EntityManager } from '@mikro-orm/postgresql';
|
||||||
import { RequiredEntityData, FilterQuery } from '@mikro-orm/core';
|
import { RequiredEntityData, FilterQuery } from '@mikro-orm/core';
|
||||||
import { Product } from '../entities/product.entity';
|
import { Product } from '../entities/product.entity';
|
||||||
import { CategoryMessage, FoodMessage, RestMessage } from 'src/common/enums/message.enum';
|
import { CategoryMessage, ProductMessage, RestMessage } from 'src/common/enums/message.enum';
|
||||||
import { RestRepository } from ../../..shops/repositories/rest.repository';
|
|
||||||
import { CacheService } from '../../../utils/cache.service';
|
|
||||||
import { Favorite } from '../entities/favorite.entity';
|
import { Favorite } from '../entities/favorite.entity';
|
||||||
|
import { Variant } from '../entities/variant.entity';
|
||||||
|
import { ShopService } from 'src/modules/shops/providers/shops.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class FoodService {
|
export class ProductService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly foodRepository: FoodRepository,
|
private readonly productRepository: ProductRepository,
|
||||||
private readonly categoryRepository: CategoryRepository,
|
private readonly categoryRepository: CategoryRepository,
|
||||||
private readonly restRepository: RestRepository,
|
private readonly shopService: ShopService,
|
||||||
private readonly em: EntityManager,
|
private readonly em: EntityManager,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
async create(restId: string, createFoodDto: CreateFoodDto) {
|
async create(shopId: string, dto: CreateProductDto) {
|
||||||
const { categoryId, ...rest } = createFoodDto;
|
const { categoryId, variants, ...rest } = dto;
|
||||||
const shop = await this.restRepository.findOne({ id: restId });
|
const shop = await this.shopService.findOrFail(shopId);
|
||||||
if (!shop) {
|
if (!shop) {
|
||||||
throw new NotFoundException(RestMessage.NOT_FOUND);
|
throw new NotFoundException(RestMessage.NOT_FOUND);
|
||||||
}
|
}
|
||||||
const category = await this.categoryRepository.findOne({ id: categoryId, shop: { id: restId } });
|
const category = await this.categoryRepository.findOne({ id: categoryId, shop: { id: shopId } });
|
||||||
if (!category) {
|
if (!category) {
|
||||||
throw new NotFoundException(CategoryMessage.NOT_FOUND);
|
throw new NotFoundException(CategoryMessage.NOT_FOUND);
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ export class FoodService {
|
|||||||
order: rest.order ?? null,
|
order: rest.order ?? null,
|
||||||
// map single-title/content DTO to localized fields
|
// map single-title/content DTO to localized fields
|
||||||
title: rest.title,
|
title: rest.title,
|
||||||
content: rest.content,
|
attribute: rest.attribute,
|
||||||
// numeric/array fields
|
// numeric/array fields
|
||||||
price: rest.price ?? 0,
|
price: rest.price ?? 0,
|
||||||
images: rest.images ?? undefined,
|
images: rest.images ?? undefined,
|
||||||
@@ -50,31 +50,41 @@ export class FoodService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const product = em.create(Product, data);
|
const product = em.create(Product, data);
|
||||||
|
|
||||||
|
em.persist(product)
|
||||||
|
|
||||||
|
for (const variant of variants) {
|
||||||
|
const variantRecord = em.create(Variant, {
|
||||||
|
product,
|
||||||
|
value: variant.value,
|
||||||
|
stock: variant.stock,
|
||||||
|
price: variant.price,
|
||||||
|
})
|
||||||
|
|
||||||
|
em.persist(variantRecord)
|
||||||
|
}
|
||||||
|
|
||||||
await em.flush();
|
await em.flush();
|
||||||
return product;
|
return product;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Re-load created entities with the primary EM to ensure they're attached
|
|
||||||
const savedFood = product?.id
|
|
||||||
? await this.foodRepository.findOne({ id: product.id }, { populate: ['category', 'shop'] })
|
|
||||||
: null;
|
|
||||||
|
|
||||||
return savedFood ?? product;
|
|
||||||
|
return product;
|
||||||
}
|
}
|
||||||
|
|
||||||
findAll(restId: string, dto: FindFoodsDto) {
|
findAll(restId: string, dto: FindProductsDto) {
|
||||||
return this.foodRepository.findAllPaginated(restId, dto);
|
return this.productRepository.findAllPaginated(restId, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Public product detail (only active products are visible).
|
async findPublicById(productId: string, userId?: string): Promise<any> {
|
||||||
*/
|
|
||||||
async findPublicById(foodId: string, userId?: string): Promise<any> {
|
const product = await this.findOrFail(productId)
|
||||||
const product = await this.foodRepository.findOne({ id: foodId, isActive: true }, { populate: ['category'] });
|
|
||||||
if (!product) throw new NotFoundException(FoodMessage.NOT_FOUND);
|
|
||||||
let isFavorite = false;
|
let isFavorite = false;
|
||||||
if (userId) {
|
if (userId) {
|
||||||
isFavorite = (await this.em.count(Favorite, { user: { id: userId }, product: { id: foodId } })) > 0;
|
isFavorite = (await this.em.count(Favorite, { user: { id: userId }, product: { id: productId } })) > 0;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...product,
|
...product,
|
||||||
@@ -82,44 +92,33 @@ export class FoodService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Admin product detail (scoped to the authenticated shop).
|
|
||||||
*/
|
|
||||||
async findAdminById(restId: string, id: string): Promise<Product> {
|
|
||||||
const product = await this.foodRepository.findOne({ id, shop: { id: restId } }, { populate: ['category'] });
|
|
||||||
|
|
||||||
if (!product) throw new NotFoundException(FoodMessage.NOT_FOUND);
|
async findAdminById(shopId: string, productId: string): Promise<Product> {
|
||||||
|
const product = await this.findOrFail(productId)
|
||||||
|
|
||||||
|
if (product.shop.id !== shopId) throw new NotFoundException(ProductMessage.NOT_FOUND);
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Find active products for a shop.
|
async findByShop(slug: string): Promise<Product[]> {
|
||||||
* @param slug - Shop slug identifier
|
const shop = await this.shopService.findOrFailBySlug( slug );
|
||||||
* @returns Array of active products
|
|
||||||
*/
|
|
||||||
async findByWeekDateAndMealType(slug: string): Promise<Product[]> {
|
|
||||||
const shop = await this.restRepository.findOne({ slug });
|
|
||||||
if (!shop) {
|
|
||||||
throw new NotFoundException(RestMessage.NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
const queryFilter: FilterQuery<Product> = {
|
const queryFilter: FilterQuery<Product> = {
|
||||||
shop: { slug },
|
shop: { slug },
|
||||||
isActive: true,
|
isActive: true,
|
||||||
} as unknown as FilterQuery<Product>;
|
} as unknown as FilterQuery<Product>;
|
||||||
|
|
||||||
return this.foodRepository.find(queryFilter, {
|
return this.productRepository.find(queryFilter, {
|
||||||
populate: ['category'],
|
populate: ['category'],
|
||||||
orderBy: { order: 'asc' }
|
orderBy: { order: 'asc' }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(restId: string, id: string, dto: Partial<CreateFoodDto>): Promise<Product> {
|
async update(restId: string, productId: string, dto: Partial<CreateProductDto>): Promise<Product> {
|
||||||
const { categoryId, ...rest } = dto;
|
const { categoryId, variants, ...rest } = dto;
|
||||||
const product = await this.foodRepository.findOne({ id, shop: { id: restId } }, { populate: ['shop'] });
|
|
||||||
if (!product) {
|
const product = await this.findOrFail(productId)
|
||||||
throw new NotFoundException(FoodMessage.NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
// attach new categories if provided (adds, does not attempt to preserve/remove existing ones)
|
// attach new categories if provided (adds, does not attempt to preserve/remove existing ones)
|
||||||
if (categoryId) {
|
if (categoryId) {
|
||||||
@@ -132,44 +131,80 @@ export class FoodService {
|
|||||||
this.em.assign(product, { category: category });
|
this.em.assign(product, { category: category });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (variants) {
|
||||||
|
// Get existing variants for this product
|
||||||
|
const existingVariants = product.variants
|
||||||
|
|
||||||
|
// Create a map of existing variants by id for easy lookup
|
||||||
|
const existingVariantsMap = new Map(existingVariants.map((v: any) => [v.id, v]));
|
||||||
|
|
||||||
|
// Track which existing variants are being updated (to avoid deletion)
|
||||||
|
const updatedVariantIds = new Set<string>();
|
||||||
|
|
||||||
|
for (const variant of variants) {
|
||||||
|
const { id, value, stock, price } = variant;
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
// Update existing variant
|
||||||
|
const existingVariant = existingVariantsMap.get(id);
|
||||||
|
if (!existingVariant) {
|
||||||
|
throw new NotFoundException('Variant not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the variant fields
|
||||||
|
this.em.assign(existingVariant, { value, stock, price });
|
||||||
|
updatedVariantIds.add(id);
|
||||||
|
} else {
|
||||||
|
// Create new variant
|
||||||
|
const variantRecord = this.em.create(Variant, {
|
||||||
|
product,
|
||||||
|
value,
|
||||||
|
stock,
|
||||||
|
price,
|
||||||
|
});
|
||||||
|
this.em.persist(variantRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete variants that exist but were not included in the update
|
||||||
|
for (const existingVariant of existingVariants) {
|
||||||
|
if (!updatedVariantIds.has((existingVariant as any).id)) {
|
||||||
|
this.em.remove(existingVariant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// assign other fields from DTO (excluding dailyStock handled below)
|
// assign other fields from DTO (excluding dailyStock handled below)
|
||||||
this.em.assign(product, rest);
|
this.em.assign(product, rest);
|
||||||
|
|
||||||
await this.em.persistAndFlush(product);
|
await this.em.persistAndFlush(product);
|
||||||
|
|
||||||
// Re-load the product to ensure populated relations and stable instance
|
|
||||||
const savedFood = await this.foodRepository.findOne({ id: product.id }, { populate: ['category', 'shop'] });
|
|
||||||
|
|
||||||
// Invalidate cache for the shop if present (optional)
|
return product;
|
||||||
// await this.invalidateRestaurantFoodsCache(savedFood?.shop?.slug);
|
|
||||||
|
|
||||||
return savedFood ?? product;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async remove(restId: string, id: string): Promise<void> {
|
async remove(restId: string, id: string): Promise<void> {
|
||||||
const product = await this.foodRepository.findOne({ id, shop: { id: restId } }, { populate: ['shop'] });
|
const product = await this.findOrFail(id)
|
||||||
if (!product) {
|
|
||||||
throw new NotFoundException(FoodMessage.NOT_FOUND);
|
if (product.shop.id !== restId) {
|
||||||
|
throw new BadRequestException("Product doesnt belongs to you")
|
||||||
}
|
}
|
||||||
|
|
||||||
// const restaurantSlug = product.shop.slug;
|
|
||||||
product.deletedAt = new Date();
|
product.deletedAt = new Date();
|
||||||
await this.em.persistAndFlush(product);
|
|
||||||
|
|
||||||
// Invalidate cache for the shop
|
await this.em.flush();
|
||||||
// await this.invalidateRestaurantFoodsCache(restaurantSlug);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async toggleFavorite(userId: string, foodId: string) {
|
async toggleFavorite(userId: string, productId: string) {
|
||||||
|
|
||||||
const favorite = await this.em.findOne(Favorite, { user: userId, product: foodId });
|
const favorite = await this.em.findOne(Favorite, { user: userId, product: productId });
|
||||||
if (favorite) {
|
if (favorite) {
|
||||||
return this.em.removeAndFlush(favorite);
|
return this.em.removeAndFlush(favorite);
|
||||||
}
|
}
|
||||||
const newFavorite = this.em.create(Favorite, {
|
const newFavorite = this.em.create(Favorite, {
|
||||||
user: userId,
|
user: userId,
|
||||||
product: foodId,
|
product: productId,
|
||||||
});
|
});
|
||||||
return this.em.persistAndFlush(newFavorite);
|
return this.em.persistAndFlush(newFavorite);
|
||||||
}
|
}
|
||||||
@@ -179,10 +214,14 @@ export class FoodService {
|
|||||||
return this.em.find(Favorite, { user: userId, product: { shop: { id: restId } } }, { populate: ['product'] });
|
return this.em.find(Favorite, { user: userId, product: { shop: { id: restId } } }, { populate: ['product'] });
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Invalidate cache for shop products
|
* Helper
|
||||||
*/
|
*/
|
||||||
// private async invalidateRestaurantFoodsCache(slug: string): Promise<void> {
|
async findOrFail(productId: string) {
|
||||||
// const cacheKey = `${this.FOODS_BY_RESTAURANT_CACHE_KEY_PREFIX}${slug}`;
|
const product = await this.productRepository.findOne({ id: productId, isActive: true },
|
||||||
// await this.cacheService.del(cacheKey);
|
{ populate: ['category', 'variants', 'shop'] });
|
||||||
// }
|
|
||||||
|
if (!product) throw new NotFoundException(ProductMessage.NOT_FOUND);
|
||||||
|
|
||||||
|
return product
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type FindFoodsOpts = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class FoodRepository extends EntityRepository<Product> {
|
export class ProductRepository extends EntityRepository<Product> {
|
||||||
constructor(readonly em: EntityManager) {
|
constructor(readonly em: EntityManager) {
|
||||||
super(em, Product);
|
super(em, Product);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
|
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
|
||||||
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
|
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
|
||||||
import { UserId } from 'src/common/decorators/user-id.decorator';
|
import { UserId } from 'src/common/decorators/user-id.decorator';
|
||||||
import { RestId } from 'src/common/decorators/rest-id.decorator';
|
import { ShopId } from 'src/common/decorators/rest-id.decorator';
|
||||||
import { ReviewStatus } from '../enums/review-status.enum';
|
import { ReviewStatus } from '../enums/review-status.enum';
|
||||||
import { Permissions } from 'src/common/decorators/permissions.decorator';
|
import { Permissions } from 'src/common/decorators/permissions.decorator';
|
||||||
import { Permission } from 'src/common/enums/permission.enum';
|
import { Permission } from 'src/common/enums/permission.enum';
|
||||||
@@ -27,7 +27,7 @@ import { API_HEADER_SLUG } from 'src/common/constants';
|
|||||||
@ApiTags('review')
|
@ApiTags('review')
|
||||||
@Controller()
|
@Controller()
|
||||||
export class ReviewController {
|
export class ReviewController {
|
||||||
constructor(private readonly reviewService: ReviewService) {}
|
constructor(private readonly reviewService: ReviewService) { }
|
||||||
|
|
||||||
@UseGuards(AuthGuard)
|
@UseGuards(AuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@@ -113,7 +113,7 @@ export class ReviewController {
|
|||||||
@ApiQuery({ name: 'status', required: false, enum: ReviewStatus })
|
@ApiQuery({ name: 'status', required: false, enum: ReviewStatus })
|
||||||
@ApiQuery({ name: 'orderBy', required: false, type: String })
|
@ApiQuery({ name: 'orderBy', required: false, type: String })
|
||||||
@ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
|
@ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
|
||||||
findAllAdmin(@Query() dto: FindReviewsDto, @RestId() restId: string) {
|
findAllAdmin(@Query() dto: FindReviewsDto, @ShopId() restId: string) {
|
||||||
return this.reviewService.findAll({ ...dto, restId: restId });
|
return this.reviewService.findAll({ ...dto, restId: restId });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ export class ReviewController {
|
|||||||
@Get('admin/reviews/:id')
|
@Get('admin/reviews/:id')
|
||||||
@ApiOperation({ summary: 'review detail' })
|
@ApiOperation({ summary: 'review detail' })
|
||||||
@ApiParam({ name: 'id', required: true })
|
@ApiParam({ name: 'id', required: true })
|
||||||
reviewDetail(@Param('id') reviewId: string, @RestId() restaurantId: string) {
|
reviewDetail(@Param('id') reviewId: string, @ShopId() restaurantId: string) {
|
||||||
return this.reviewService.findById(reviewId, restaurantId);
|
return this.reviewService.findById(reviewId, restaurantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ export class ReviewController {
|
|||||||
changeStatus(
|
changeStatus(
|
||||||
@Param('id') reviewId: string,
|
@Param('id') reviewId: string,
|
||||||
@Body() changeStatusDto: ChangeStatusDto,
|
@Body() changeStatusDto: ChangeStatusDto,
|
||||||
@RestId() restaurantId: string,
|
@ShopId() restaurantId: string,
|
||||||
) {
|
) {
|
||||||
return this.reviewService.changeStatus(reviewId, changeStatusDto.status, restaurantId);
|
return this.reviewService.changeStatus(reviewId, changeStatusDto.status, restaurantId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export class RolesController {
|
|||||||
@Permissions(Permission.MANAGE_ROLES)
|
@Permissions(Permission.MANAGE_ROLES)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOperation({ summary: 'Get all through shop roles with pagination and filters' })
|
@ApiOperation({ summary: 'Get all through shop roles with pagination and filters' })
|
||||||
findAll(@RestId() restId: string) {
|
findAll(@ShopId() restId: string) {
|
||||||
return this.roleService.findAllGeneralAndRestaurantRoles(restId);
|
return this.roleService.findAllGeneralAndRestaurantRoles(restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ export class RolesController {
|
|||||||
@Permissions(Permission.MANAGE_ROLES)
|
@Permissions(Permission.MANAGE_ROLES)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOperation({ summary: 'Get all permissions that the admin has' })
|
@ApiOperation({ summary: 'Get all permissions that the admin has' })
|
||||||
async findAllPermissions(@AdminId() adminId: string, @RestId() restId: string) {
|
async findAllPermissions(@AdminId() adminId: string, @ShopId() restId: string) {
|
||||||
const adminPermissionNames = await this.permissionService.getAdminFullPermissions(adminId, restId);
|
const adminPermissionNames = await this.permissionService.getAdminFullPermissions(adminId, restId);
|
||||||
|
|
||||||
return adminPermissionNames;
|
return adminPermissionNames;
|
||||||
@@ -49,7 +49,7 @@ export class RolesController {
|
|||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOperation({ summary: 'Create a new role' })
|
@ApiOperation({ summary: 'Create a new role' })
|
||||||
@ApiBody({ type: CreateRoleDto })
|
@ApiBody({ type: CreateRoleDto })
|
||||||
create(@Body() dto: CreateRoleDto, @RestId() restId: string) {
|
create(@Body() dto: CreateRoleDto, @ShopId() restId: string) {
|
||||||
return this.roleService.createRestaurantRole(dto, restId);
|
return this.roleService.createRestaurantRole(dto, restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ export class RolesController {
|
|||||||
@Permissions(Permission.MANAGE_ROLES)
|
@Permissions(Permission.MANAGE_ROLES)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOperation({ summary: 'Get a specific role by ID' })
|
@ApiOperation({ summary: 'Get a specific role by ID' })
|
||||||
findOne(@Param('id') id: string, @RestId() restId: string) {
|
findOne(@Param('id') id: string, @ShopId() restId: string) {
|
||||||
return this.roleService.findOne(restId, id);
|
return this.roleService.findOne(restId, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ export class RolesController {
|
|||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOperation({ summary: 'Update a role' })
|
@ApiOperation({ summary: 'Update a role' })
|
||||||
@ApiBody({ type: UpdateRoleDto })
|
@ApiBody({ type: UpdateRoleDto })
|
||||||
update(@Param('id') id: string, @Body() dto: UpdateRoleDto, @RestId() restId: string) {
|
update(@Param('id') id: string, @Body() dto: UpdateRoleDto, @ShopId() restId: string) {
|
||||||
return this.roleService.update(restId, id, dto);
|
return this.roleService.update(restId, id, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ export class RolesController {
|
|||||||
@Permissions(Permission.MANAGE_ROLES)
|
@Permissions(Permission.MANAGE_ROLES)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOperation({ summary: 'Delete a role' })
|
@ApiOperation({ summary: 'Delete a role' })
|
||||||
remove(@Param('id') id: string, @RestId() restId: string) {
|
remove(@Param('id') id: string, @ShopId() restId: string) {
|
||||||
return this.roleService.remove(restId, id);
|
return this.roleService.remove(restId, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { UpdateScheduleDto } from '../dto/update-schedule.dto';
|
|||||||
import { FindSchedulesDto } from '../dto/find-schedules.dto';
|
import { FindSchedulesDto } from '../dto/find-schedules.dto';
|
||||||
import { Schedule } from '../entities/schedule.entity';
|
import { Schedule } from '../entities/schedule.entity';
|
||||||
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
|
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
|
||||||
import { RestId } from 'src/common/decorators/rest-id.decorator';
|
import { ShopId } from 'src/common/decorators/rest-id.decorator';
|
||||||
import { Permissions } from 'src/common/decorators/permissions.decorator';
|
import { Permissions } from 'src/common/decorators/permissions.decorator';
|
||||||
import { Permission } from 'src/common/enums/permission.enum';
|
import { Permission } from 'src/common/enums/permission.enum';
|
||||||
import { API_HEADER_SLUG } from 'src/common/constants';
|
import { API_HEADER_SLUG } from 'src/common/constants';
|
||||||
@@ -45,7 +45,7 @@ export class ScheduleController {
|
|||||||
@ApiOperation({ summary: 'Create a new schedule' })
|
@ApiOperation({ summary: 'Create a new schedule' })
|
||||||
@ApiBody({ type: CreateScheduleDto })
|
@ApiBody({ type: CreateScheduleDto })
|
||||||
@ApiCreatedResponse({ description: 'Schedule created successfully', type: Schedule })
|
@ApiCreatedResponse({ description: 'Schedule created successfully', type: Schedule })
|
||||||
create(@Body() createScheduleDto: CreateScheduleDto, @RestId() restId: string) {
|
create(@Body() createScheduleDto: CreateScheduleDto, @ShopId() restId: string) {
|
||||||
return this.scheduleService.create(restId, createScheduleDto);
|
return this.scheduleService.create(restId, createScheduleDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ export class ScheduleController {
|
|||||||
@ApiOkResponse({ description: 'List of schedules', type: [Schedule] })
|
@ApiOkResponse({ description: 'List of schedules', type: [Schedule] })
|
||||||
findAll(
|
findAll(
|
||||||
@Query(new ValidationPipe({ transform: true, whitelist: true })) query: FindSchedulesDto,
|
@Query(new ValidationPipe({ transform: true, whitelist: true })) query: FindSchedulesDto,
|
||||||
@RestId() restId: string,
|
@ShopId() restId: string,
|
||||||
) {
|
) {
|
||||||
return this.scheduleService.findAll(restId, query);
|
return this.scheduleService.findAll(restId, query);
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ export class ScheduleController {
|
|||||||
@ApiParam({ name: 'id', description: 'Schedule ID' })
|
@ApiParam({ name: 'id', description: 'Schedule ID' })
|
||||||
@ApiOkResponse({ description: 'Schedule details', type: Schedule })
|
@ApiOkResponse({ description: 'Schedule details', type: Schedule })
|
||||||
@ApiNotFoundResponse({ description: 'Schedule not found' })
|
@ApiNotFoundResponse({ description: 'Schedule not found' })
|
||||||
findOne(@Param('id') id: string, @RestId() restId: string) {
|
findOne(@Param('id') id: string, @ShopId() restId: string) {
|
||||||
return this.scheduleService.findOne(id, restId);
|
return this.scheduleService.findOne(id, restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ export class ScheduleController {
|
|||||||
@ApiBody({ type: UpdateScheduleDto })
|
@ApiBody({ type: UpdateScheduleDto })
|
||||||
@ApiOkResponse({ description: 'Schedule updated successfully', type: Schedule })
|
@ApiOkResponse({ description: 'Schedule updated successfully', type: Schedule })
|
||||||
@ApiNotFoundResponse({ description: 'Schedule not found' })
|
@ApiNotFoundResponse({ description: 'Schedule not found' })
|
||||||
update(@Param('id') id: string, @Body() updateScheduleDto: UpdateScheduleDto, @RestId() restId: string) {
|
update(@Param('id') id: string, @Body() updateScheduleDto: UpdateScheduleDto, @ShopId() restId: string) {
|
||||||
return this.scheduleService.update(id, restId, updateScheduleDto);
|
return this.scheduleService.update(id, restId, updateScheduleDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ export class ScheduleController {
|
|||||||
@ApiParam({ name: 'id', description: 'Schedule ID' })
|
@ApiParam({ name: 'id', description: 'Schedule ID' })
|
||||||
@ApiOkResponse({ description: 'Schedule deleted successfully' })
|
@ApiOkResponse({ description: 'Schedule deleted successfully' })
|
||||||
@ApiNotFoundResponse({ description: 'Schedule not found' })
|
@ApiNotFoundResponse({ description: 'Schedule not found' })
|
||||||
remove(@Param('id') id: string, @RestId() restId: string) {
|
remove(@Param('id') id: string, @ShopId() restId: string) {
|
||||||
return this.scheduleService.remove(id, restId);
|
return this.scheduleService.remove(id, restId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Controller, Get, Post, Body, Patch, Param, UseGuards, Delete, Query } from '@nestjs/common';
|
import { Controller, Get, Post, Body, Patch, Param, UseGuards, Delete, Query } from '@nestjs/common';
|
||||||
import { RestaurantsService } from ../../../shops.service';
|
import { RestaurantsService } from ../../../ shops.service';
|
||||||
import { CreateRestaurantDto } from '../dto/create-shop.dto';
|
import { CreateRestaurantDto } from '../dto/create-shop.dto';
|
||||||
import { UpdateRestaurantDto } from '../dto/update-shop.dto';
|
import { UpdateRestaurantDto } from '../dto/update-shop.dto';
|
||||||
import { UpgradeSubscriptionDto } from '../dto/upgrade-subscription.dto';
|
import { UpgradeSubscriptionDto } from '../dto/upgrade-subscription.dto';
|
||||||
import { FindRestaurantsDto } from ../../../shops.dto';
|
import { FindRestaurantsDto } from ../../../ shops.dto';
|
||||||
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
|
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
|
||||||
import {
|
import {
|
||||||
ApiBearerAuth,
|
ApiBearerAuth,
|
||||||
@@ -41,7 +41,7 @@ export class RestaurantsController {
|
|||||||
@Permissions(Permission.UPDATE_RESTAURANT)
|
@Permissions(Permission.UPDATE_RESTAURANT)
|
||||||
@ApiOperation({ summary: 'Get shop by ID from request' })
|
@ApiOperation({ summary: 'Get shop by ID from request' })
|
||||||
@Get('admin/shops/my-shop')
|
@Get('admin/shops/my-shop')
|
||||||
async findOne(@RestId() restId: string) {
|
async findOne(@ShopId() restId: string) {
|
||||||
return await this.restaurantsService.findOne(restId);
|
return await this.restaurantsService.findOne(restId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ export class RestaurantsController {
|
|||||||
@ApiOperation({ summary: 'Update a shop' })
|
@ApiOperation({ summary: 'Update a shop' })
|
||||||
@ApiBody({ type: UpdateRestaurantDto })
|
@ApiBody({ type: UpdateRestaurantDto })
|
||||||
@Patch('admin/shops/my-shop')
|
@Patch('admin/shops/my-shop')
|
||||||
updateMyRestaurant(@RestId() restId: string, @Body() updateRestaurantDto: UpdateRestaurantDto) {
|
updateMyRestaurant(@ShopId() restId: string, @Body() updateRestaurantDto: UpdateRestaurantDto) {
|
||||||
return this.restaurantsService.update(restId, updateRestaurantDto);
|
return this.restaurantsService.update(restId, updateRestaurantDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { ScheduleRepository } from '../repositories/schedule.repository';
|
|||||||
import { CreateScheduleDto } from '../dto/create-schedule.dto';
|
import { CreateScheduleDto } from '../dto/create-schedule.dto';
|
||||||
import { UpdateScheduleDto } from '../dto/update-schedule.dto';
|
import { UpdateScheduleDto } from '../dto/update-schedule.dto';
|
||||||
import { FindSchedulesDto } from '../dto/find-schedules.dto';
|
import { FindSchedulesDto } from '../dto/find-schedules.dto';
|
||||||
import { RestRepository } from '../repositories/rest.repository';
|
import { shopRepository } from '../repositories/rest.repository';
|
||||||
import { Shop } from '../entities/shop.entity';
|
import { Shop } from '../entities/shop.entity';
|
||||||
import { RestMessage } from 'src/common/enums/message.enum';
|
import { RestMessage } from 'src/common/enums/message.enum';
|
||||||
// import { RestMessage } from 'src/common/enums/message.enum';
|
// import { RestMessage } from 'src/common/enums/message.enum';
|
||||||
@@ -15,9 +15,9 @@ import { RestMessage } from 'src/common/enums/message.enum';
|
|||||||
export class ScheduleService {
|
export class ScheduleService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly scheduleRepository: ScheduleRepository,
|
private readonly scheduleRepository: ScheduleRepository,
|
||||||
private readonly restRepository: RestRepository,
|
private readonly restRepository: shopRepository,
|
||||||
private readonly em: EntityManager,
|
private readonly em: EntityManager,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
async create(restId: string, createScheduleDto: CreateScheduleDto): Promise<Schedule> {
|
async create(restId: string, createScheduleDto: CreateScheduleDto): Promise<Schedule> {
|
||||||
const rest = await this.restRepository.findOne({ id: restId });
|
const rest = await this.restRepository.findOne({ id: restId });
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { UpdateRestaurantDto } from '../dto/update-shop.dto';
|
|||||||
import { UpgradeSubscriptionDto } from '../dto/upgrade-subscription.dto';
|
import { UpgradeSubscriptionDto } from '../dto/upgrade-subscription.dto';
|
||||||
import { Shop } from '../entities/shop.entity';
|
import { Shop } from '../entities/shop.entity';
|
||||||
import { EntityManager } from '@mikro-orm/postgresql';
|
import { EntityManager } from '@mikro-orm/postgresql';
|
||||||
import { RestRepository } from '../repositories/rest.repository';
|
import { shopRepository } from '../repositories/rest.repository';
|
||||||
import { RestMessage } from 'src/common/enums/message.enum';
|
import { RestMessage } from 'src/common/enums/message.enum';
|
||||||
import { FindRestaurantsDto } from ../../..shops.dto';
|
import { FindRestaurantsDto } from '../providers/shops.dto';
|
||||||
import { PaginatedResult } from 'src/common/interfaces/pagination.interface';
|
import { PaginatedResult } from 'src/common/interfaces/pagination.interface';
|
||||||
import { PlanEnum } from '../interface/plan.interface';
|
import { PlanEnum } from '../interface/plan.interface';
|
||||||
import { Admin } from '../../../admin/entities/admin.entity';
|
import { Admin } from '../../../admin/entities/admin.entity';
|
||||||
@@ -18,8 +18,8 @@ import { NotificationPreference } from '../../../notifications/entities/notifica
|
|||||||
import { notificationPreferencesData } from '../../../../seeders/data/notification-preferences.data';
|
import { notificationPreferencesData } from '../../../../seeders/data/notification-preferences.data';
|
||||||
import { Order } from '../../../orders/entities/order.entity';
|
import { Order } from '../../../orders/entities/order.entity';
|
||||||
import { Coupon } from '../../../coupons/entities/coupon.entity';
|
import { Coupon } from '../../../coupons/entities/coupon.entity';
|
||||||
import { Category } from ../../..products/entities/category.entity';
|
import { Category } from ../../..products / entities / category.entity';
|
||||||
import { Product } from ../../..products/entities/product.entity';
|
import { Product } from ../../..products / entities / product.entity';
|
||||||
import { Delivery } from '../../../delivery/entities/delivery.entity';
|
import { Delivery } from '../../../delivery/entities/delivery.entity';
|
||||||
import { PaymentMethod } from '../../../payments/entities/payment-method.entity';
|
import { PaymentMethod } from '../../../payments/entities/payment-method.entity';
|
||||||
import { Pager } from '../../../pager/entities/pager.entity';
|
import { Pager } from '../../../pager/entities/pager.entity';
|
||||||
@@ -30,10 +30,10 @@ import { Notification } from '../../../notifications/entities/notification.entit
|
|||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RestaurantsService {
|
export class ShopService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly em: EntityManager,
|
private readonly em: EntityManager,
|
||||||
private readonly restRepository: RestRepository,
|
private readonly shopRepository: shopRepository,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
async setupRestuarant(dto: CreateRestaurantDto): Promise<Shop> {
|
async setupRestuarant(dto: CreateRestaurantDto): Promise<Shop> {
|
||||||
@@ -107,7 +107,7 @@ export class RestaurantsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findAll(dto: FindRestaurantsDto): Promise<PaginatedResult<Shop>> {
|
async findAll(dto: FindRestaurantsDto): Promise<PaginatedResult<Shop>> {
|
||||||
return this.restRepository.findAllPaginated({
|
return this.shopRepository.findAllPaginated({
|
||||||
page: dto.page,
|
page: dto.page,
|
||||||
limit: dto.limit,
|
limit: dto.limit,
|
||||||
search: dto.search,
|
search: dto.search,
|
||||||
@@ -129,7 +129,7 @@ export class RestaurantsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findOne(id: string): Promise<Shop> {
|
async findOne(id: string): Promise<Shop> {
|
||||||
const shop = await this.restRepository.findOne({ id });
|
const shop = await this.shopRepository.findOne({ id });
|
||||||
|
|
||||||
if (!shop) {
|
if (!shop) {
|
||||||
throw new NotFoundException(RestMessage.NOT_FOUND);
|
throw new NotFoundException(RestMessage.NOT_FOUND);
|
||||||
@@ -140,7 +140,7 @@ export class RestaurantsService {
|
|||||||
|
|
||||||
async findOneBySubscriptionId(subscriptionId: string): Promise<Shop> {
|
async findOneBySubscriptionId(subscriptionId: string): Promise<Shop> {
|
||||||
console.log('subscriptionId', subscriptionId)
|
console.log('subscriptionId', subscriptionId)
|
||||||
const shop = await this.restRepository.findOne({ subscriptionId });
|
const shop = await this.shopRepository.findOne({ subscriptionId });
|
||||||
console.log('shop', shop)
|
console.log('shop', shop)
|
||||||
if (!shop) {
|
if (!shop) {
|
||||||
throw new NotFoundException(RestMessage.NOT_FOUND);
|
throw new NotFoundException(RestMessage.NOT_FOUND);
|
||||||
@@ -155,7 +155,7 @@ export class RestaurantsService {
|
|||||||
// TODO : it must be done inside transaction
|
// TODO : it must be done inside transaction
|
||||||
async update(id: string, dto: UpdateRestaurantDto): Promise<Shop> {
|
async update(id: string, dto: UpdateRestaurantDto): Promise<Shop> {
|
||||||
|
|
||||||
const shop = await this.restRepository.findOne({ id: id });
|
const shop = await this.shopRepository.findOne({ id: id });
|
||||||
|
|
||||||
if (!shop) {
|
if (!shop) {
|
||||||
throw new NotFoundException(RestMessage.NOT_FOUND);
|
throw new NotFoundException(RestMessage.NOT_FOUND);
|
||||||
@@ -186,7 +186,7 @@ export class RestaurantsService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.restRepository.assign(shop, dto);
|
this.shopRepository.assign(shop, dto);
|
||||||
|
|
||||||
await this.em.persistAndFlush(shop);
|
await this.em.persistAndFlush(shop);
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ export class RestaurantsService {
|
|||||||
|
|
||||||
async remove(id: string) {
|
async remove(id: string) {
|
||||||
// Soft delete the shop by setting isActive to false
|
// Soft delete the shop by setting isActive to false
|
||||||
const shop = await this.restRepository.findOne({ id });
|
const shop = await this.shopRepository.findOne({ id });
|
||||||
|
|
||||||
if (!shop) {
|
if (!shop) {
|
||||||
throw new NotFoundException(RestMessage.NOT_FOUND);
|
throw new NotFoundException(RestMessage.NOT_FOUND);
|
||||||
@@ -208,7 +208,7 @@ export class RestaurantsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async upgradeSubscription(subscriptionId: string, dto: UpgradeSubscriptionDto): Promise<Shop> {
|
async upgradeSubscription(subscriptionId: string, dto: UpgradeSubscriptionDto): Promise<Shop> {
|
||||||
const shop = await this.restRepository.findOne({ subscriptionId });
|
const shop = await this.shopRepository.findOne({ subscriptionId });
|
||||||
|
|
||||||
if (!shop) {
|
if (!shop) {
|
||||||
throw new NotFoundException(RestMessage.NOT_FOUND);
|
throw new NotFoundException(RestMessage.NOT_FOUND);
|
||||||
@@ -278,4 +278,19 @@ export class RestaurantsService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findOrFail(shopId: string) {
|
||||||
|
const shop = await this.shopRepository.findOne({ id: shopId }, { populate: ['deliveries'] })
|
||||||
|
if (!shop) {
|
||||||
|
throw new BadRequestException("Shop not found")
|
||||||
|
}
|
||||||
|
return shop
|
||||||
|
}
|
||||||
|
|
||||||
|
async findOrFailBySlug(shopSlug: string) {
|
||||||
|
const shop = await this.shopRepository.findOne({ slug: shopSlug }, { populate: ['deliveries'] })
|
||||||
|
if (!shop) {
|
||||||
|
throw new BadRequestException("Shop not found")
|
||||||
|
}
|
||||||
|
return shop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type FindRestaurantsOpts = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RestRepository extends EntityRepository<Shop> {
|
export class shopRepository extends EntityRepository<Shop> {
|
||||||
constructor(readonly em: EntityManager) {
|
constructor(readonly em: EntityManager) {
|
||||||
super(em, Shop);
|
super(em, Shop);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { ShopsService } from './providers/shops.service';
|
|||||||
import { ShopsController } from './controllers/shops.controller';
|
import { ShopsController } from './controllers/shops.controller';
|
||||||
import { MikroOrmModule } from '@mikro-orm/nestjs';
|
import { MikroOrmModule } from '@mikro-orm/nestjs';
|
||||||
import { Shop } from './entities/shop.entity';
|
import { Shop } from './entities/shop.entity';
|
||||||
import { RestRepository } from './repositories/rest.repository';
|
import { shopRepository } from './repositories/rest.repository';
|
||||||
import { ScheduleRepository } from './repositories/schedule.repository';
|
import { ScheduleRepository } from './repositories/schedule.repository';
|
||||||
import { Schedule } from './entities/schedule.entity';
|
import { Schedule } from './entities/schedule.entity';
|
||||||
import { ScheduleService } from './providers/schedule.service';
|
import { ScheduleService } from './providers/schedule.service';
|
||||||
@@ -14,8 +14,8 @@ import { AuthModule } from '../auth/auth.module';
|
|||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
controllers: [ShopsController, ScheduleController],
|
controllers: [ShopsController, ScheduleController],
|
||||||
providers: [ShopsService, RestRepository, ScheduleRepository, ScheduleService, ShopCrone],
|
providers: [ShopsService, shopRepository, ScheduleRepository, ScheduleService, ShopCrone],
|
||||||
imports: [MikroOrmModule.forFeature([Shop, Schedule]), JwtModule, forwardRef(() => AuthModule)],
|
imports: [MikroOrmModule.forFeature([Shop, Schedule]), JwtModule, forwardRef(() => AuthModule)],
|
||||||
exports: [RestRepository, ScheduleRepository, ScheduleService],
|
exports: [shopRepository, ScheduleRepository, ScheduleService],
|
||||||
})
|
})
|
||||||
export class ShopsModule {}
|
export class ShopsModule { }
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export class UsersController {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly userService: UserService,
|
private readonly userService: UserService,
|
||||||
private readonly walletService: WalletService,
|
private readonly walletService: WalletService,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
@UseGuards(AuthGuard)
|
@UseGuards(AuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@@ -39,7 +39,7 @@ export class UsersController {
|
|||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@ApiBody({ type: UpdateUserDto })
|
@ApiBody({ type: UpdateUserDto })
|
||||||
@Patch('public/user/update')
|
@Patch('public/user/update')
|
||||||
async updateUser(@UserId() userId: string, @RestId() restId: string, @Body() dto: UpdateUserDto) {
|
async updateUser(@UserId() userId: string, @ShopId() restId: string, @Body() dto: UpdateUserDto) {
|
||||||
const user = await this.userService.updateUser(userId, restId, dto);
|
const user = await this.userService.updateUser(userId, restId, dto);
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ export class UsersController {
|
|||||||
@ApiOperation({ summary: 'Get User Wallet' })
|
@ApiOperation({ summary: 'Get User Wallet' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@Get('public/user/wallet/balance')
|
@Get('public/user/wallet/balance')
|
||||||
async getUserWalletBalance(@UserId() userId: string, @RestId() restId: string) {
|
async getUserWalletBalance(@UserId() userId: string, @ShopId() restId: string) {
|
||||||
const wallet = await this.walletService.getUserCurrentWalletBalance(userId, restId);
|
const wallet = await this.walletService.getUserCurrentWalletBalance(userId, restId);
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ export class UsersController {
|
|||||||
@ApiOperation({ summary: 'Get User Wallet' })
|
@ApiOperation({ summary: 'Get User Wallet' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@Get('public/user/points/balance')
|
@Get('public/user/points/balance')
|
||||||
async getUserWallet(@UserId() userId: string, @RestId() restId: string) {
|
async getUserWallet(@UserId() userId: string, @ShopId() restId: string) {
|
||||||
const wallet = await this.walletService.getUserCurrentPoinrBalance(userId, restId);
|
const wallet = await this.walletService.getUserCurrentPoinrBalance(userId, restId);
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ export class UsersController {
|
|||||||
@Get('public/user/wallet/transactions')
|
@Get('public/user/wallet/transactions')
|
||||||
async getUserWalletTransactions(
|
async getUserWalletTransactions(
|
||||||
@UserId() userId: string,
|
@UserId() userId: string,
|
||||||
@RestId() restId: string,
|
@ShopId() restId: string,
|
||||||
@Query(new ValidationPipe({ transform: true, whitelist: true }))
|
@Query(new ValidationPipe({ transform: true, whitelist: true }))
|
||||||
query: FindWalletTransactionsDto,
|
query: FindWalletTransactionsDto,
|
||||||
) {
|
) {
|
||||||
@@ -159,7 +159,7 @@ export class UsersController {
|
|||||||
@ApiOperation({ summary: 'Convert user score (points) to wallet balance' })
|
@ApiOperation({ summary: 'Convert user score (points) to wallet balance' })
|
||||||
@ApiHeader(API_HEADER_SLUG)
|
@ApiHeader(API_HEADER_SLUG)
|
||||||
@Post('public/user/convert-score-to-wallet')
|
@Post('public/user/convert-score-to-wallet')
|
||||||
async convertScoreToWallet(@UserId() userId: string, @RestId() restId: string) {
|
async convertScoreToWallet(@UserId() userId: string, @ShopId() restId: string) {
|
||||||
await this.userService.convertScoreToWallet(userId, restId);
|
await this.userService.convertScoreToWallet(userId, restId);
|
||||||
return {
|
return {
|
||||||
message: UserSuccessMessage.SCORE_CONVERTED_SUCCESS,
|
message: UserSuccessMessage.SCORE_CONVERTED_SUCCESS,
|
||||||
@@ -176,7 +176,7 @@ export class UsersController {
|
|||||||
async findAllRestaurantUsers(
|
async findAllRestaurantUsers(
|
||||||
@Query(new ValidationPipe({ transform: true, whitelist: true }))
|
@Query(new ValidationPipe({ transform: true, whitelist: true }))
|
||||||
query: FindUsersDto,
|
query: FindUsersDto,
|
||||||
@RestId() restId: string,
|
@ShopId() restId: string,
|
||||||
) {
|
) {
|
||||||
return this.userService.findAll(restId, query);
|
return this.userService.findAll(restId, query);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user