production
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,27 +0,0 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
export class Migration20260105085439 extends Migration {
|
||||
|
||||
override async up(): Promise<void> {
|
||||
this.addSql(`alter table "point_transactions" drop constraint if exists "point_transactions_type_check";`);
|
||||
|
||||
this.addSql(`alter table "categories" add column "order" int null;`);
|
||||
|
||||
this.addSql(`alter table "point_transactions" add constraint "point_transactions_type_check" check("type" in (''));`);
|
||||
}
|
||||
|
||||
override async down(): Promise<void> {
|
||||
this.addSql(`create table "user_wallets" ("id" char(26) not null, "created_at" timestamptz(6) not null default now(), "updated_at" timestamptz(6) not null default now(), "deleted_at" timestamptz(6) null, "restaurant_id" char(26) not null, "user_id" char(26) not null, "wallet" int4 not null default 0, "points" int4 not null default 0, constraint "user_wallets_pkey" primary key ("id"));`);
|
||||
this.addSql(`alter table "user_wallets" add constraint "unique_user_restaurant" unique ("user_id", "restaurant_id");`);
|
||||
this.addSql(`create index "user_wallets_created_at_index" on "user_wallets" ("created_at");`);
|
||||
this.addSql(`create index "user_wallets_deleted_at_index" on "user_wallets" ("deleted_at");`);
|
||||
this.addSql(`create index "user_wallets_restaurant_id_index" on "user_wallets" ("restaurant_id");`);
|
||||
this.addSql(`create index "user_wallets_user_id_index" on "user_wallets" ("user_id");`);
|
||||
this.addSql(`create index "user_wallets_user_id_restaurant_id_index" on "user_wallets" ("user_id", "restaurant_id");`);
|
||||
|
||||
this.addSql(`alter table "point_transactions" drop constraint if exists "point_transactions_type_check";`);
|
||||
|
||||
this.addSql(`alter table "point_transactions" add constraint "point_transactions_type_check" check("type" in (''));`);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
export class Migration20260106054151 extends Migration {
|
||||
|
||||
override async up(): Promise<void> {
|
||||
this.addSql(`alter table "restaurants" alter column "subscription_id" type varchar(255) using ("subscription_id"::varchar(255));`);
|
||||
this.addSql(`alter table "restaurants" alter column "subscription_id" drop not null;`);
|
||||
this.addSql(`alter table "restaurants" alter column "subscription_end_date" type timestamptz using ("subscription_end_date"::timestamptz);`);
|
||||
this.addSql(`alter table "restaurants" alter column "subscription_end_date" drop not null;`);
|
||||
this.addSql(`alter table "restaurants" alter column "subscription_start_date" type timestamptz using ("subscription_start_date"::timestamptz);`);
|
||||
this.addSql(`alter table "restaurants" alter column "subscription_start_date" drop not null;`);
|
||||
}
|
||||
|
||||
override async down(): Promise<void> {
|
||||
this.addSql(`alter table "restaurants" alter column "subscription_id" type varchar(255) using ("subscription_id"::varchar(255));`);
|
||||
this.addSql(`alter table "restaurants" alter column "subscription_id" set not null;`);
|
||||
this.addSql(`alter table "restaurants" alter column "subscription_end_date" type timestamptz using ("subscription_end_date"::timestamptz);`);
|
||||
this.addSql(`alter table "restaurants" alter column "subscription_end_date" set not null;`);
|
||||
this.addSql(`alter table "restaurants" alter column "subscription_start_date" type timestamptz using ("subscription_start_date"::timestamptz);`);
|
||||
this.addSql(`alter table "restaurants" alter column "subscription_start_date" set not null;`);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
export class Migration20260106192946 extends Migration {
|
||||
|
||||
override async up(): Promise<void> {
|
||||
this.addSql(`alter table "contacts" add column "restaurant_id" char(26) null;`);
|
||||
this.addSql(`alter table "contacts" add constraint "contacts_restaurant_id_foreign" foreign key ("restaurant_id") references "restaurants" ("id") on update cascade on delete set null;`);
|
||||
}
|
||||
|
||||
override async down(): Promise<void> {
|
||||
this.addSql(`alter table "contacts" drop constraint "contacts_restaurant_id_foreign";`);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +1,15 @@
|
||||
import { Index, PrimaryKey, Property, Filter, OptionalProps } from '@mikro-orm/core';
|
||||
import { ulid } from 'ulid';
|
||||
import { Index, Property, Filter, OptionalProps } from '@mikro-orm/core';
|
||||
|
||||
|
||||
@Filter({ name: 'notDeleted', cond: { deletedAt: null }, default: true })
|
||||
@Index({ properties: ['deletedAt'] })
|
||||
@Index({ properties: ['createdAt'] })
|
||||
export abstract class BaseEntity {
|
||||
[OptionalProps]?: 'id' | 'createdAt' | 'updatedAt' | 'deletedAt';
|
||||
|
||||
@PrimaryKey({ type: 'string', columnType: 'char(26)' })
|
||||
id: string = ulid();
|
||||
[OptionalProps]?: 'createdAt' | 'deletedAt';
|
||||
|
||||
@Property({ defaultRaw: 'now()', columnType: 'timestamptz' })
|
||||
createdAt: Date = new Date();
|
||||
|
||||
@Property({
|
||||
onUpdate: () => new Date(),
|
||||
defaultRaw: 'now()',
|
||||
columnType: 'timestamptz',
|
||||
})
|
||||
updatedAt: Date = new Date();
|
||||
|
||||
@Property({ nullable: true })
|
||||
@Property({ nullable: true, columnType: 'timestamptz' })
|
||||
deletedAt?: Date;
|
||||
}
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
|
||||
import { CategoryService } from '../providers/category.service';
|
||||
import { CreateCategoryDto } from '../dto/create-category.dto';
|
||||
import { UpdateCategoryDto } from '../dto/update-category.dto';
|
||||
import {
|
||||
ApiTags,
|
||||
ApiOperation,
|
||||
ApiCreatedResponse,
|
||||
ApiOkResponse,
|
||||
ApiNotFoundResponse,
|
||||
ApiParam,
|
||||
ApiBody,
|
||||
ApiBearerAuth,
|
||||
ApiHeader,
|
||||
} from '@nestjs/swagger';
|
||||
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
|
||||
import { UseGuards } from '@nestjs/common';
|
||||
import { RestId } from 'src/common/decorators';
|
||||
import { Permission } from 'src/common/enums/permission.enum';
|
||||
import { Permissions } from 'src/common/decorators/permissions.decorator';
|
||||
import { API_HEADER_SLUG } from 'src/common/constants';
|
||||
|
||||
@ApiTags('category')
|
||||
@Controller()
|
||||
export class CategoryController {
|
||||
constructor(private readonly categoryService: CategoryService) { }
|
||||
|
||||
@Get('public/categories/restaurant/:slug')
|
||||
@ApiOperation({ summary: 'Get all categories by restaurant slug' })
|
||||
@ApiHeader(API_HEADER_SLUG)
|
||||
@ApiParam({ name: 'slug', required: true, description: 'Restaurant Slug' })
|
||||
@ApiOkResponse({ description: 'List of all categories for the restaurant' })
|
||||
findAllByRestaurant(@Param('slug') slug: string) {
|
||||
return this.categoryService.findAllByRestaurant(slug);
|
||||
}
|
||||
|
||||
/*** Admin ***/
|
||||
|
||||
@ApiOperation({ summary: 'Create category' })
|
||||
@ApiBody({ type: CreateCategoryDto })
|
||||
@Permissions(Permission.MANAGE_CATEGORIES)
|
||||
@UseGuards(AdminAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Post('admin/categories')
|
||||
create(@Body() dto: CreateCategoryDto, @RestId() restId: string) {
|
||||
return this.categoryService.create(restId, dto);
|
||||
}
|
||||
@Permissions(Permission.MANAGE_CATEGORIES)
|
||||
@ApiOperation({ summary: 'my restaurant categories' })
|
||||
@UseGuards(AdminAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('admin/categories')
|
||||
findAll(@RestId() restId: string) {
|
||||
return this.categoryService.findAllByRestaurantId(restId);
|
||||
}
|
||||
|
||||
@Permissions(Permission.MANAGE_CATEGORIES)
|
||||
@UseGuards(AdminAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('admin/categories/:id')
|
||||
@ApiOperation({ summary: 'Get category' })
|
||||
@ApiParam({ name: 'id', required: true, type: String })
|
||||
findOne(@Param('id') id: string, @RestId() restId: string) {
|
||||
return this.categoryService.findOne(restId, id);
|
||||
}
|
||||
|
||||
@UseGuards(AdminAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Permissions(Permission.MANAGE_CATEGORIES)
|
||||
@Patch('admin/categories/:id')
|
||||
@ApiOperation({ summary: 'Update category' })
|
||||
@ApiParam({ name: 'id' })
|
||||
@ApiBody({ type: UpdateCategoryDto })
|
||||
update(@Param('id') id: string, @Body() dto: UpdateCategoryDto, @RestId() restId: string) {
|
||||
return this.categoryService.update(restId, id, dto);
|
||||
}
|
||||
|
||||
@UseGuards(AdminAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Permissions(Permission.MANAGE_CATEGORIES)
|
||||
@Delete('admin/categories/:id')
|
||||
@ApiOperation({ summary: 'Delete category' })
|
||||
@ApiParam({ name: 'id' })
|
||||
@ApiOkResponse({ description: 'Deleted' })
|
||||
remove(@Param('id') id: string, @RestId() restId: string) {
|
||||
return this.categoryService.remove(restId, id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { Cron } from '@nestjs/schedule';
|
||||
import { EntityManager } from '@mikro-orm/postgresql';
|
||||
import { Inventory } from '../../inventory/entities/inventory.entity';
|
||||
|
||||
@Injectable()
|
||||
export class productStockCrone {
|
||||
private readonly logger = new Logger(productStockCrone.name);
|
||||
|
||||
constructor(private readonly em: EntityManager) { }
|
||||
|
||||
// run every day at 00:03
|
||||
@Cron('3 0 * * *', {
|
||||
name: 'resetAvailableStock',
|
||||
timeZone: 'UTC',
|
||||
})
|
||||
async handleCron() {
|
||||
try {
|
||||
this.logger.debug('Starting daily inventory reset (availableStock = totalStock)');
|
||||
|
||||
const inventories = await this.em.find(Inventory, {});
|
||||
if (!inventories || inventories.length === 0) {
|
||||
this.logger.debug('No inventory records found to reset');
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.log(`Resetting available stock for ${inventories.length} inventory records`);
|
||||
|
||||
await this.em.transactional(async em => {
|
||||
for (const inv of inventories) {
|
||||
// reload inside transaction to avoid concurrency issues
|
||||
const record = await em.findOne(Inventory, { id: inv.id });
|
||||
if (!record) continue;
|
||||
record.availableStock = record.totalStock;
|
||||
em.persist(record);
|
||||
}
|
||||
await em.flush();
|
||||
});
|
||||
|
||||
this.logger.log('Daily inventory reset completed');
|
||||
} catch (err) {
|
||||
this.logger.error(`productStockCrone failed: ${err?.message}`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Entity, Property, ManyToOne } from '@mikro-orm/core';
|
||||
import { BaseEntity } from '../../../common/entities/base.entity';
|
||||
import { Attribute } from './attribute.entity';
|
||||
|
||||
@Entity({ tableName: 'attribute_values' })
|
||||
export class AttributeValue extends BaseEntity {
|
||||
@Property({ primary: true })
|
||||
id: bigint;
|
||||
|
||||
@Property()
|
||||
value: string;
|
||||
|
||||
@ManyToOne(() => Attribute)
|
||||
attribute: Attribute;
|
||||
|
||||
@Property({ type: 'bigint' })
|
||||
attributeId: bigint;
|
||||
|
||||
@Property({ type: 'int', nullable: true })
|
||||
sortOrder?: number;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Entity, Enum, Property } from '@mikro-orm/core';
|
||||
import { BaseEntity } from '../../../common/entities/base.entity';
|
||||
import { AttributeType } from '../interface/product.interface';
|
||||
|
||||
@Entity({ tableName: 'attributes' })
|
||||
export class Attribute extends BaseEntity {
|
||||
@Property({ primary: true })
|
||||
id: bigint;
|
||||
|
||||
@Property()
|
||||
name: string;
|
||||
|
||||
@Enum()
|
||||
type: AttributeType;
|
||||
|
||||
@Property({ type: 'boolean', default: false })
|
||||
isRequired: boolean = false;
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import { Entity, Index, Property, Collection, OneToMany, ManyToOne } from '@mikro-orm/core';
|
||||
import { product } from './product.entity';
|
||||
import { BaseEntity } from '../../../common/entities/base.entity';
|
||||
import { Restaurant } from 'src/modules/restaurants/entities/restaurant.entity';
|
||||
|
||||
@Entity({ tableName: 'categories' })
|
||||
@Index({ properties: ['restaurant', 'isActive'] })
|
||||
@Index({ properties: ['isActive'] })
|
||||
export class Category extends BaseEntity {
|
||||
@Property()
|
||||
title!: string;
|
||||
|
||||
@OneToMany(() => product, product => product.category)
|
||||
products = new Collection<product>(this);
|
||||
|
||||
@Property({ default: true })
|
||||
isActive: boolean = true;
|
||||
|
||||
@ManyToOne(() => Restaurant)
|
||||
restaurant!: Restaurant;
|
||||
|
||||
@Property({ nullable: true })
|
||||
avatarUrl?: string;
|
||||
|
||||
@Property({ type: 'int', nullable: true })
|
||||
order?: number;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { Entity, ManyToOne, Unique } from '@mikro-orm/core';
|
||||
import { BaseEntity } from '../../../common/entities/base.entity';
|
||||
import { User } from '../../user/entities/user.entity';
|
||||
import { product } from '../../products/entities/product.entity';
|
||||
|
||||
@Entity({ tableName: 'favorites' })
|
||||
@Unique({ properties: ['user', 'product'] })
|
||||
export class Favorite extends BaseEntity {
|
||||
@ManyToOne(() => User)
|
||||
user: User;
|
||||
|
||||
@ManyToOne(() => product)
|
||||
product: product;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import { Entity, Property } from '@mikro-orm/core';
|
||||
import { BaseEntity } from '../../../common/entities/base.entity';
|
||||
|
||||
|
||||
@Entity({ tableName: 'products' })
|
||||
export class product extends BaseEntity {
|
||||
|
||||
|
||||
@Property({ nullable: true })
|
||||
title?: string;
|
||||
|
||||
@Property({ type: 'text', nullable: true })
|
||||
linkUrl?: string;
|
||||
|
||||
|
||||
@Property({ type: 'boolean', default: true })
|
||||
isActive: boolean = true;
|
||||
|
||||
@Property({ type: 'json', nullable: true })
|
||||
images?: string[];
|
||||
|
||||
|
||||
}
|
||||
@@ -4,20 +4,19 @@ import { BaseEntity } from '../../../common/entities/base.entity';
|
||||
|
||||
@Entity({ tableName: 'products' })
|
||||
export class product extends BaseEntity {
|
||||
@Property({ primary: true })
|
||||
id: bigint
|
||||
|
||||
|
||||
@Property({ nullable: true })
|
||||
title?: string;
|
||||
@Property()
|
||||
title: string;
|
||||
|
||||
@Property({ type: 'text', nullable: true })
|
||||
linkUrl?: string;
|
||||
|
||||
|
||||
@Property({ type: 'boolean', default: true })
|
||||
isActive: boolean = true;
|
||||
|
||||
@Property({ type: 'json', nullable: true })
|
||||
images?: string[];
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export enum MealType {
|
||||
BREAKFAST = 'breakfast',
|
||||
LUNCH = 'lunch',
|
||||
DINNER = 'dinner',
|
||||
SNACK = 'snack',
|
||||
}
|
||||
export enum AttributeType{
|
||||
SELECT='select',
|
||||
TEXT='text',
|
||||
NUMBER='number',
|
||||
CHECKBOX='checkbox',
|
||||
BOOLEAN='boolean',
|
||||
}
|
||||
|
||||
@@ -2,14 +2,12 @@ import { Module } from '@nestjs/common';
|
||||
import { productService } from './providers/product.service';
|
||||
import { productStockCrone } from './crone/product.crone';
|
||||
import { productController } from './controllers/product.controller';
|
||||
import { CategoryController } from './controllers/category.controller';
|
||||
import { CategoryService } from './providers/category.service';
|
||||
import { productRepository } from './repositories/product.repository';
|
||||
import { CategoryRepository } from './repositories/category.repository';
|
||||
import { MikroOrmModule } from '@mikro-orm/nestjs';
|
||||
import { Category } from './entities/category.entity';
|
||||
import { product } from './entities/product.entity';
|
||||
import { RestaurantsModule } from '../restaurants/restaurants.module';
|
||||
import { Attribute } from './entities/attribute.entity';
|
||||
import { AttributeValue } from './entities/attribute-value.entity';
|
||||
import { AuthModule } from '../auth/auth.module';
|
||||
import { JwtModule } from '@nestjs/jwt';
|
||||
import { UtilsModule } from '../util/utils.module';
|
||||
@@ -17,14 +15,13 @@ import { Favorite } from './entities/favorite.entity';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
MikroOrmModule.forFeature([product, Category, Favorite]),
|
||||
RestaurantsModule,
|
||||
MikroOrmModule.forFeature([product, Category, Favorite, Attribute, AttributeValue]),
|
||||
AuthModule,
|
||||
JwtModule,
|
||||
UtilsModule,
|
||||
],
|
||||
controllers: [productController, CategoryController],
|
||||
providers: [productService, CategoryService, productRepository, CategoryRepository, productStockCrone],
|
||||
exports: [productRepository, CategoryRepository],
|
||||
controllers: [productController,],
|
||||
providers: [productService, productRepository, productStockCrone],
|
||||
exports: [productRepository,],
|
||||
})
|
||||
export class productModule { }
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { CreateCategoryDto } from '../dto/create-category.dto';
|
||||
import { UpdateCategoryDto } from '../dto/update-category.dto';
|
||||
import { CategoryRepository } from '../repositories/category.repository';
|
||||
import { EntityManager } from '@mikro-orm/postgresql';
|
||||
import { RequiredEntityData } from '@mikro-orm/core';
|
||||
import { Category } from '../entities/category.entity';
|
||||
import { CategoryMessage, RestMessage } from 'src/common/enums/message.enum';
|
||||
import { Restaurant } from 'src/modules/restaurants/entities/restaurant.entity';
|
||||
|
||||
@Injectable()
|
||||
export class CategoryService {
|
||||
constructor(
|
||||
private readonly categoryRepository: CategoryRepository,
|
||||
private readonly em: EntityManager,
|
||||
) { }
|
||||
|
||||
async create(restId: string, dto: CreateCategoryDto): Promise<Category> {
|
||||
const restaurant = await this.em.findOne(Restaurant, { id: restId });
|
||||
if (!restaurant) {
|
||||
throw new NotFoundException(RestMessage.NOT_FOUND);
|
||||
}
|
||||
const data: RequiredEntityData<Category> = {
|
||||
title: dto.title,
|
||||
isActive: dto.isActive ?? true,
|
||||
restaurant: restaurant,
|
||||
avatarUrl: dto.avatarUrl,
|
||||
};
|
||||
|
||||
const category = this.categoryRepository.create(data);
|
||||
await this.em.persistAndFlush(category);
|
||||
return category;
|
||||
}
|
||||
|
||||
async findAllByRestaurant(slug: string): Promise<Category[]> {
|
||||
const restaurant = await this.em.findOne(Restaurant, { slug });
|
||||
if (!restaurant || !restaurant.id) {
|
||||
throw new NotFoundException(RestMessage.NOT_FOUND);
|
||||
}
|
||||
return this.categoryRepository.find({ restaurant: restaurant, isActive: true });
|
||||
}
|
||||
|
||||
async findAllByRestaurantId(restId: string): Promise<Category[]> {
|
||||
return this.categoryRepository.find({ restaurant: { id: restId } });
|
||||
}
|
||||
|
||||
// async findAll(opts?: { restId?: string; isActive?: boolean }): Promise<Category[]> {
|
||||
// const where: FilterQuery<Category> = {};
|
||||
// if (opts?.restId) where.restId = opts.restId;
|
||||
// if (opts && typeof opts.isActive === 'boolean') where.isActive = opts.isActive;
|
||||
// const cats = await this.categoryRepository.find(where, { populate: ['products'] });
|
||||
|
||||
// // Return plain objects to avoid circular references during JSON serialization
|
||||
// return cats.map(cat => ({
|
||||
// id: cat.id,
|
||||
// title: cat.title,
|
||||
// isActive: cat.isActive,
|
||||
// restId: cat.restId,
|
||||
// avatarUrl: cat.avatarUrl,
|
||||
// createdAt: cat.createdAt,
|
||||
// updatedAt: cat.updatedAt,
|
||||
// products: cat.products.getItems().map(f => ({ id: f.id, title: f.title })),
|
||||
// })) as unknown as Category[];
|
||||
// }
|
||||
|
||||
async findOne(restId: string, id: string): Promise<Category> {
|
||||
const cat = await this.categoryRepository.findOne({ id, restaurant: { id: restId } }, { populate: ['products'] });
|
||||
if (!cat) throw new NotFoundException(CategoryMessage.NOT_FOUND);
|
||||
|
||||
return {
|
||||
id: cat.id,
|
||||
title: cat.title,
|
||||
isActive: cat.isActive,
|
||||
restaurant: cat.restaurant,
|
||||
avatarUrl: cat.avatarUrl,
|
||||
createdAt: cat.createdAt,
|
||||
updatedAt: cat.updatedAt,
|
||||
products: cat.products.getItems().map(f => ({ id: f.id, title: f.title })),
|
||||
} as unknown as Category;
|
||||
}
|
||||
|
||||
async findRestaurantCategories(restId: string): Promise<Category> {
|
||||
const cat = await this.categoryRepository.findOne({ restaurant: { id: restId } }, { populate: ['products'] });
|
||||
if (!cat) throw new NotFoundException(CategoryMessage.NOT_FOUND);
|
||||
|
||||
return {
|
||||
id: cat.id,
|
||||
title: cat.title,
|
||||
isActive: cat.isActive,
|
||||
restaurant: cat.restaurant,
|
||||
avatarUrl: cat.avatarUrl,
|
||||
createdAt: cat.createdAt,
|
||||
updatedAt: cat.updatedAt,
|
||||
} as unknown as Category;
|
||||
}
|
||||
|
||||
async update(restId: string, id: string, dto: UpdateCategoryDto): Promise<Category> {
|
||||
const cat = await this.categoryRepository.findOne({ id, restaurant: { id: restId } });
|
||||
if (!cat) throw new NotFoundException(CategoryMessage.NOT_FOUND);
|
||||
this.em.assign(cat, dto);
|
||||
await this.em.persistAndFlush(cat);
|
||||
return cat;
|
||||
}
|
||||
|
||||
async remove(restId: string, id: string): Promise<void> {
|
||||
const cat = await this.categoryRepository.findOne({ id, restaurant: { id: restId } });
|
||||
if (!cat) throw new NotFoundException(CategoryMessage.NOT_FOUND);
|
||||
cat.deletedAt = new Date();
|
||||
await this.em.persistAndFlush(cat);
|
||||
}
|
||||
}
|
||||
@@ -2,29 +2,19 @@ import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { CreateproductDto } from '../dto/create-product.dto';
|
||||
import { FindproductsDto } from '../dto/find-products.dto';
|
||||
import { productRepository } from '../repositories/product.repository';
|
||||
import { CategoryRepository } from '../repositories/category.repository';
|
||||
import { EntityManager } from '@mikro-orm/postgresql';
|
||||
import { RequiredEntityData, FilterQuery } from '@mikro-orm/core';
|
||||
import { product } from '../entities/product.entity';
|
||||
import { CategoryMessage, productMessage, RestMessage } from 'src/common/enums/message.enum';
|
||||
import { RestRepository } from 'src/modules/restaurants/repositories/rest.repository';
|
||||
import { CacheService } from '../../util/cache.service';
|
||||
import { Favorite } from '../entities/favorite.entity';
|
||||
import { MealType } from '../interface/product.interface';
|
||||
import { Inventory } from 'src/modules/inventory/entities/inventory.entity';
|
||||
|
||||
@Injectable()
|
||||
export class productService {
|
||||
private readonly productS_BY_RESTAURANT_CACHE_KEY_PREFIX = 'products:restaurant:';
|
||||
private readonly productS_CACHE_TTL = 600; // 10 minutes in seconds
|
||||
|
||||
constructor(
|
||||
private readonly productRepository: productRepository,
|
||||
private readonly categoryRepository: CategoryRepository,
|
||||
private readonly restRepository: RestRepository,
|
||||
private readonly em: EntityManager,
|
||||
private readonly cacheService: CacheService,
|
||||
) { }
|
||||
) { }
|
||||
|
||||
async create(restId: string, createproductDto: CreateproductDto) {
|
||||
const { categoryId, dailyStock = 0, ...rest } = createproductDto;
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { EntityManager, EntityRepository } from '@mikro-orm/postgresql';
|
||||
import { Category } from '../entities/category.entity';
|
||||
|
||||
@Injectable()
|
||||
export class CategoryRepository extends EntityRepository<Category> {
|
||||
constructor(readonly em: EntityManager) {
|
||||
super(em, Category);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
export interface CategoryData {
|
||||
title: string;
|
||||
restaurantSlug: string;
|
||||
|
||||
Reference in New Issue
Block a user