Spaces:
Sleeping
Sleeping
Trần Viết Sơn
commited on
Commit
•
95a812a
1
Parent(s):
4a51d88
feat: update order
Browse files- backend/src/common/interfaces/jwt-payload.interface.ts +5 -0
- backend/src/entities/order.entity.ts +11 -3
- backend/src/migrations/1730895089788-UpdateOrderFieldTime.ts +25 -0
- backend/src/modules/order/dto/create-order.dto.ts +4 -0
- backend/src/modules/order/dto/update-order.dto.ts +14 -0
- backend/src/modules/order/order.controller.ts +40 -16
- backend/src/modules/order/order.module.ts +2 -2
- backend/src/modules/order/order.service.ts +181 -85
backend/src/common/interfaces/jwt-payload.interface.ts
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
interface JwtPayload {
|
2 |
+
sub: string; // id người dùng
|
3 |
+
roles: string; // quyền người dùng
|
4 |
+
username: string;
|
5 |
+
}
|
backend/src/entities/order.entity.ts
CHANGED
@@ -2,6 +2,7 @@ import {
|
|
2 |
BaseEntity,
|
3 |
Column,
|
4 |
CreateDateColumn,
|
|
|
5 |
Entity,
|
6 |
JoinColumn,
|
7 |
ManyToOne,
|
@@ -9,6 +10,7 @@ import {
|
|
9 |
OneToOne,
|
10 |
PrimaryGeneratedColumn,
|
11 |
Relation,
|
|
|
12 |
} from 'typeorm';
|
13 |
import { BranchEntity } from './branch.entity.js';
|
14 |
import { UserEntity } from './user.entity.js';
|
@@ -55,9 +57,6 @@ export class OrderEntity extends BaseEntity {
|
|
55 |
@Column()
|
56 |
total_value: number;
|
57 |
|
58 |
-
@CreateDateColumn()
|
59 |
-
create_at: Date;
|
60 |
-
|
61 |
@Column({ default: 0 })
|
62 |
order_type: number;
|
63 |
|
@@ -73,4 +72,13 @@ export class OrderEntity extends BaseEntity {
|
|
73 |
@OneToOne(() => PaymentEntity, (a) => a.order)
|
74 |
@JoinColumn({ name: 'payment_id' })
|
75 |
payment: Relation<PaymentEntity>;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
}
|
|
|
2 |
BaseEntity,
|
3 |
Column,
|
4 |
CreateDateColumn,
|
5 |
+
DeleteDateColumn,
|
6 |
Entity,
|
7 |
JoinColumn,
|
8 |
ManyToOne,
|
|
|
10 |
OneToOne,
|
11 |
PrimaryGeneratedColumn,
|
12 |
Relation,
|
13 |
+
UpdateDateColumn,
|
14 |
} from 'typeorm';
|
15 |
import { BranchEntity } from './branch.entity.js';
|
16 |
import { UserEntity } from './user.entity.js';
|
|
|
57 |
@Column()
|
58 |
total_value: number;
|
59 |
|
|
|
|
|
|
|
60 |
@Column({ default: 0 })
|
61 |
order_type: number;
|
62 |
|
|
|
72 |
@OneToOne(() => PaymentEntity, (a) => a.order)
|
73 |
@JoinColumn({ name: 'payment_id' })
|
74 |
payment: Relation<PaymentEntity>;
|
75 |
+
|
76 |
+
@CreateDateColumn()
|
77 |
+
created_at: Date;
|
78 |
+
|
79 |
+
@UpdateDateColumn()
|
80 |
+
updated_at: Date;
|
81 |
+
|
82 |
+
@DeleteDateColumn()
|
83 |
+
deleted_at: Date;
|
84 |
}
|
backend/src/migrations/1730895089788-UpdateOrderFieldTime.ts
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { MigrationInterface, QueryRunner } from 'typeorm';
|
2 |
+
|
3 |
+
export class UpdateOrderFieldTime1730895089788 implements MigrationInterface {
|
4 |
+
name = 'UpdateOrderFieldTime1730895089788';
|
5 |
+
|
6 |
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
7 |
+
await queryRunner.query(`ALTER TABLE "orders" DROP COLUMN "create_at"`);
|
8 |
+
await queryRunner.query(
|
9 |
+
`ALTER TABLE "orders" ADD "created_at" TIMESTAMP NOT NULL DEFAULT now()`,
|
10 |
+
);
|
11 |
+
await queryRunner.query(
|
12 |
+
`ALTER TABLE "orders" ADD "updated_at" TIMESTAMP NOT NULL DEFAULT now()`,
|
13 |
+
);
|
14 |
+
await queryRunner.query(`ALTER TABLE "orders" ADD "deleted_at" TIMESTAMP`);
|
15 |
+
}
|
16 |
+
|
17 |
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
18 |
+
await queryRunner.query(
|
19 |
+
`ALTER TABLE "orders" ADD "create_at" TIMESTAMP NOT NULL DEFAULT now()`,
|
20 |
+
);
|
21 |
+
await queryRunner.query(`ALTER TABLE "orders" DROP COLUMN "deleted_at"`);
|
22 |
+
await queryRunner.query(`ALTER TABLE "orders" DROP COLUMN "updated_at"`);
|
23 |
+
await queryRunner.query(`ALTER TABLE "orders" DROP COLUMN "created_at"`);
|
24 |
+
}
|
25 |
+
}
|
backend/src/modules/order/dto/create-order.dto.ts
CHANGED
@@ -16,6 +16,10 @@ export class CreateOrderDto {
|
|
16 |
@IsNumber()
|
17 |
table_number?: number;
|
18 |
|
|
|
|
|
|
|
|
|
19 |
@IsNumber()
|
20 |
order_type: number;
|
21 |
|
|
|
16 |
@IsNumber()
|
17 |
table_number?: number;
|
18 |
|
19 |
+
@IsOptional()
|
20 |
+
@IsString()
|
21 |
+
note?: string;
|
22 |
+
|
23 |
@IsNumber()
|
24 |
order_type: number;
|
25 |
|
backend/src/modules/order/dto/update-order.dto.ts
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { IsArray, IsNumber, IsOptional, ValidateNested } from 'class-validator';
|
2 |
+
import { OrderItemsDto } from './order-items.dto.js';
|
3 |
+
import { Type } from 'class-transformer';
|
4 |
+
|
5 |
+
export class UpdateOrderDto {
|
6 |
+
@IsOptional()
|
7 |
+
@IsNumber()
|
8 |
+
table_number?: number;
|
9 |
+
|
10 |
+
@IsArray()
|
11 |
+
@ValidateNested()
|
12 |
+
@Type(() => OrderItemsDto)
|
13 |
+
order_items: OrderItemsDto[];
|
14 |
+
}
|
backend/src/modules/order/order.controller.ts
CHANGED
@@ -11,9 +11,12 @@ import {
|
|
11 |
import { OrderService } from './order.service.js';
|
12 |
import { CreateOrderDto } from './dto/create-order.dto.js';
|
13 |
import { Role } from '../../common/enums/role.enum.js';
|
|
|
|
|
|
|
14 |
|
15 |
@Controller('branchs/:branchId/orders')
|
16 |
-
export class
|
17 |
constructor(private readonly orderService: OrderService) {}
|
18 |
|
19 |
@Post()
|
@@ -25,13 +28,14 @@ export class OrderController {
|
|
25 |
const userId = req['user'].sub;
|
26 |
const role = req['user'].roles;
|
27 |
console.log(req['user']);
|
28 |
-
if (role
|
|
|
29 |
return this.orderService.createFromCustomer(
|
30 |
branchId,
|
31 |
userId,
|
32 |
createOrderDto,
|
33 |
);
|
34 |
-
else
|
35 |
return this.orderService.createFromStaff(
|
36 |
branchId,
|
37 |
userId,
|
@@ -39,30 +43,50 @@ export class OrderController {
|
|
39 |
);
|
40 |
}
|
41 |
|
42 |
-
@Get()
|
43 |
-
async
|
44 |
-
|
45 |
-
|
|
|
|
|
|
|
46 |
const userId = req['user'].sub;
|
47 |
console.log(req['user']);
|
48 |
-
return this.orderService.
|
49 |
}
|
50 |
|
51 |
@Get(':id')
|
52 |
async findOne(@Param('id') id: string) {
|
53 |
return this.orderService.findOne(+id);
|
54 |
}
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
// @Body() updateOrderDto: UpdateOrderDto,
|
60 |
-
// ) {
|
61 |
-
// return this.orderService.update(+id, updateOrderDto);
|
62 |
-
// }
|
63 |
|
64 |
@Delete(':id')
|
65 |
remove(@Param('id') id: string) {
|
66 |
return this.orderService.remove(+id);
|
67 |
}
|
68 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
import { OrderService } from './order.service.js';
|
12 |
import { CreateOrderDto } from './dto/create-order.dto.js';
|
13 |
import { Role } from '../../common/enums/role.enum.js';
|
14 |
+
import { paginate, Paginate, PaginateQuery } from 'nestjs-paginate';
|
15 |
+
import { Roles } from '../authentication/authorization/roles.decorator.js';
|
16 |
+
import { UpdateOrderDto } from './dto/update-order.dto.js';
|
17 |
|
18 |
@Controller('branchs/:branchId/orders')
|
19 |
+
export class BranchOrderController {
|
20 |
constructor(private readonly orderService: OrderService) {}
|
21 |
|
22 |
@Post()
|
|
|
28 |
const userId = req['user'].sub;
|
29 |
const role = req['user'].roles;
|
30 |
console.log(req['user']);
|
31 |
+
if (role === Role.CUSTOMER) {
|
32 |
+
console.log('customer');
|
33 |
return this.orderService.createFromCustomer(
|
34 |
branchId,
|
35 |
userId,
|
36 |
createOrderDto,
|
37 |
);
|
38 |
+
} else
|
39 |
return this.orderService.createFromStaff(
|
40 |
branchId,
|
41 |
userId,
|
|
|
43 |
);
|
44 |
}
|
45 |
|
46 |
+
@Get('history')
|
47 |
+
async findHistory(
|
48 |
+
@Req() req: Request,
|
49 |
+
@Param('branchId') branchId: string,
|
50 |
+
@Paginate() paginateQuery: PaginateQuery,
|
51 |
+
) {
|
52 |
+
// order history of user.
|
53 |
const userId = req['user'].sub;
|
54 |
console.log(req['user']);
|
55 |
+
return this.orderService.findHistory(paginateQuery, userId, branchId);
|
56 |
}
|
57 |
|
58 |
@Get(':id')
|
59 |
async findOne(@Param('id') id: string) {
|
60 |
return this.orderService.findOne(+id);
|
61 |
}
|
62 |
+
@Patch(':id')
|
63 |
+
update(@Param('id') id: string, @Body() updateOrderDto: UpdateOrderDto) {
|
64 |
+
return this.orderService.updateOrder(+id, updateOrderDto);
|
65 |
+
}
|
|
|
|
|
|
|
|
|
66 |
|
67 |
@Delete(':id')
|
68 |
remove(@Param('id') id: string) {
|
69 |
return this.orderService.remove(+id);
|
70 |
}
|
71 |
}
|
72 |
+
|
73 |
+
@Roles(Role.ADMIN, Role.STAFF, Role.BRANCH_MANAGER, Role.SHIPPER)
|
74 |
+
@Controller('orders')
|
75 |
+
export class OrderController {
|
76 |
+
constructor(private readonly orderService: OrderService) {}
|
77 |
+
|
78 |
+
@Get()
|
79 |
+
async findAll(@Paginate() paginateQuery: PaginateQuery) {
|
80 |
+
return this.orderService.findAll(paginateQuery);
|
81 |
+
}
|
82 |
+
|
83 |
+
@Get(':id')
|
84 |
+
async findOne(@Param('id') id: string) {
|
85 |
+
return this.orderService.findOne(+id);
|
86 |
+
}
|
87 |
+
|
88 |
+
@Patch(':id')
|
89 |
+
update(@Param('id') id: string, @Body() updateOrderDto: UpdateOrderDto) {
|
90 |
+
return this.orderService.updateOrder(+id, updateOrderDto);
|
91 |
+
}
|
92 |
+
}
|
backend/src/modules/order/order.module.ts
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
import { Module } from '@nestjs/common';
|
2 |
import { OrderService } from './order.service.js';
|
3 |
-
import { OrderController } from './order.controller.js';
|
4 |
import { BranchModule } from '../branch/branch.module.js';
|
5 |
import { BranchMenusModule } from '../branch-menus/branch-menus.module.js';
|
6 |
|
7 |
@Module({
|
8 |
imports: [BranchModule, BranchMenusModule],
|
9 |
-
controllers: [OrderController],
|
10 |
providers: [OrderService],
|
11 |
exports: [OrderService],
|
12 |
})
|
|
|
1 |
import { Module } from '@nestjs/common';
|
2 |
import { OrderService } from './order.service.js';
|
3 |
+
import { BranchOrderController, OrderController } from './order.controller.js';
|
4 |
import { BranchModule } from '../branch/branch.module.js';
|
5 |
import { BranchMenusModule } from '../branch-menus/branch-menus.module.js';
|
6 |
|
7 |
@Module({
|
8 |
imports: [BranchModule, BranchMenusModule],
|
9 |
+
controllers: [BranchOrderController, OrderController],
|
10 |
providers: [OrderService],
|
11 |
exports: [OrderService],
|
12 |
})
|
backend/src/modules/order/order.service.ts
CHANGED
@@ -12,10 +12,21 @@ import { isUUID } from 'class-validator';
|
|
12 |
import { OrderItemEntity } from '../../entities/order-item.entity.js';
|
13 |
import { BranchMenuEntity } from '../../entities/branch-menu.entity.js';
|
14 |
import { OrderStatus } from '../../common/enums/OrderStatus.enum.js';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
@Injectable()
|
17 |
export class OrderService {
|
18 |
-
constructor(
|
|
|
|
|
|
|
19 |
async createFromCustomer(
|
20 |
branchId: string,
|
21 |
userId: string,
|
@@ -34,44 +45,60 @@ export class OrderService {
|
|
34 |
if (!branch) {
|
35 |
throw new BadRequestException('Branch not found');
|
36 |
}
|
37 |
-
const
|
38 |
-
order.branch = branch;
|
39 |
-
order.customer = user;
|
40 |
-
order.order_type = createOrderDto.order_type;
|
41 |
-
order.order_status = OrderStatus.PENDING;
|
42 |
-
order.total_value = 0;
|
43 |
-
await order.save();
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
}
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
orderItems
|
|
|
|
|
|
|
|
|
70 |
}
|
71 |
-
await order.save();
|
72 |
-
order.total_value = totalValue;
|
73 |
-
await OrderItemEntity.save(orderItems);
|
74 |
-
return { ...order, order_items: orderItems };
|
75 |
}
|
76 |
|
77 |
async createFromStaff(
|
@@ -93,38 +120,55 @@ export class OrderService {
|
|
93 |
order.table_number = createOrderDto.table_number;
|
94 |
order.order_status = OrderStatus.PREPARING;
|
95 |
order.total_value = 0;
|
96 |
-
await order.save();
|
97 |
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
}
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
|
|
|
|
|
|
|
|
|
|
123 |
}
|
124 |
-
await order.save();
|
125 |
-
order.total_value = totalValue;
|
126 |
-
await OrderItemEntity.save(orderItems);
|
127 |
-
return { ...order, order_items: orderItems };
|
128 |
}
|
129 |
|
130 |
/**
|
@@ -133,7 +177,11 @@ export class OrderService {
|
|
133 |
async findOrderOrError(id: number) {
|
134 |
const order = await OrderEntity.findOne({
|
135 |
where: { id },
|
136 |
-
relations: [
|
|
|
|
|
|
|
|
|
137 |
});
|
138 |
if (!order) {
|
139 |
throw new NotFoundException('Order id not found');
|
@@ -141,33 +189,81 @@ export class OrderService {
|
|
141 |
return order;
|
142 |
}
|
143 |
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
const order = await this.findOrderOrError(id);
|
150 |
-
order.
|
|
|
151 |
await order.save();
|
152 |
}
|
153 |
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
//
|
163 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
}
|
165 |
|
166 |
-
findOne(id: number) {
|
167 |
-
return
|
168 |
}
|
169 |
|
170 |
-
remove(id: number) {
|
171 |
-
|
|
|
172 |
}
|
173 |
}
|
|
|
12 |
import { OrderItemEntity } from '../../entities/order-item.entity.js';
|
13 |
import { BranchMenuEntity } from '../../entities/branch-menu.entity.js';
|
14 |
import { OrderStatus } from '../../common/enums/OrderStatus.enum.js';
|
15 |
+
import {
|
16 |
+
FilterOperator,
|
17 |
+
paginate,
|
18 |
+
PaginateConfig,
|
19 |
+
PaginateQuery,
|
20 |
+
} from 'nestjs-paginate';
|
21 |
+
import { UpdateOrderDto } from './dto/update-order.dto.js';
|
22 |
+
import { DataSource } from 'typeorm';
|
23 |
|
24 |
@Injectable()
|
25 |
export class OrderService {
|
26 |
+
constructor(
|
27 |
+
private readonly branchService: BranchService,
|
28 |
+
private readonly datasource: DataSource,
|
29 |
+
) {}
|
30 |
async createFromCustomer(
|
31 |
branchId: string,
|
32 |
userId: string,
|
|
|
45 |
if (!branch) {
|
46 |
throw new BadRequestException('Branch not found');
|
47 |
}
|
48 |
+
const queryRunner = this.datasource.createQueryRunner();
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
|
50 |
+
// Start a new transaction
|
51 |
+
await queryRunner.connect();
|
52 |
+
await queryRunner.startTransaction();
|
53 |
+
|
54 |
+
try {
|
55 |
+
console.log('Customer create order');
|
56 |
+
const order = OrderEntity.create();
|
57 |
+
order.branch = branch;
|
58 |
+
order.customer = user;
|
59 |
+
order.order_type = createOrderDto.order_type;
|
60 |
+
order.order_status = OrderStatus.PENDING;
|
61 |
+
order.total_value = 0;
|
62 |
+
await queryRunner.manager.save(order);
|
63 |
+
|
64 |
+
let orderItems: OrderItemEntity[] = [];
|
65 |
+
let totalValue = 0;
|
66 |
+
for (const item of createOrderDto.order_items) {
|
67 |
+
let branchMenu: BranchMenuEntity;
|
68 |
+
if (!isUUID(item.menu_id)) {
|
69 |
+
branchMenu = await BranchMenuEntity.findOne({
|
70 |
+
where: { branch_id: branchId, menu_id: item.menu_id },
|
71 |
+
relations: ['menu_item'],
|
72 |
+
});
|
73 |
+
} else {
|
74 |
+
branchMenu = await BranchMenuEntity.findOne({
|
75 |
+
where: { branch_id: branchId, id: item.menu_id },
|
76 |
+
relations: ['menu_item'],
|
77 |
+
});
|
78 |
+
}
|
79 |
+
if (!branchMenu) {
|
80 |
+
throw new BadRequestException('Item not found in branch menu');
|
81 |
+
}
|
82 |
+
const orderItem = OrderItemEntity.create();
|
83 |
+
orderItem.branch_menu = branchMenu;
|
84 |
+
orderItem.price = branchMenu.menu_item.price;
|
85 |
+
orderItem.quantity = item.quantity;
|
86 |
+
orderItem.order_id = order.id;
|
87 |
+
totalValue += orderItem.price * orderItem.quantity;
|
88 |
+
orderItems.push(orderItem);
|
89 |
}
|
90 |
+
await queryRunner.manager.save(order);
|
91 |
+
order.total_value = totalValue;
|
92 |
+
await queryRunner.manager.save(orderItems);
|
93 |
+
|
94 |
+
await queryRunner.commitTransaction();
|
95 |
+
await queryRunner.release();
|
96 |
+
return { ...order, order_items: orderItems };
|
97 |
+
} catch (err) {
|
98 |
+
await queryRunner.rollbackTransaction();
|
99 |
+
await queryRunner.release();
|
100 |
+
throw err;
|
101 |
}
|
|
|
|
|
|
|
|
|
102 |
}
|
103 |
|
104 |
async createFromStaff(
|
|
|
120 |
order.table_number = createOrderDto.table_number;
|
121 |
order.order_status = OrderStatus.PREPARING;
|
122 |
order.total_value = 0;
|
|
|
123 |
|
124 |
+
const queryRunner = this.datasource.createQueryRunner();
|
125 |
+
|
126 |
+
// Start a new transaction
|
127 |
+
await queryRunner.connect();
|
128 |
+
await queryRunner.startTransaction();
|
129 |
+
|
130 |
+
try {
|
131 |
+
await queryRunner.manager.save(order);
|
132 |
+
|
133 |
+
let orderItems: OrderItemEntity[] = [];
|
134 |
+
let totalValue = 0;
|
135 |
+
for (const item of createOrderDto.order_items) {
|
136 |
+
let branchMenu: BranchMenuEntity;
|
137 |
+
if (!isUUID(item.menu_id)) {
|
138 |
+
branchMenu = await BranchMenuEntity.findOne({
|
139 |
+
where: { branch_id: branchId, menu_id: item.menu_id },
|
140 |
+
relations: ['menu_item'],
|
141 |
+
});
|
142 |
+
} else {
|
143 |
+
branchMenu = await BranchMenuEntity.findOne({
|
144 |
+
where: { branch_id: branchId, id: item.menu_id },
|
145 |
+
relations: ['menu_item'],
|
146 |
+
});
|
147 |
+
}
|
148 |
+
if (!branchMenu) {
|
149 |
+
throw new BadRequestException('Item not found in branch menu');
|
150 |
+
}
|
151 |
+
const orderItem = OrderItemEntity.create();
|
152 |
+
orderItem.branch_menu = branchMenu;
|
153 |
+
orderItem.price = branchMenu.menu_item.price;
|
154 |
+
orderItem.quantity = item.quantity;
|
155 |
+
orderItem.order_id = order.id;
|
156 |
+
totalValue += orderItem.price * orderItem.quantity;
|
157 |
+
orderItems.push(orderItem);
|
158 |
}
|
159 |
+
await queryRunner.manager.save(order);
|
160 |
+
order.total_value = totalValue;
|
161 |
+
await queryRunner.manager.save(orderItems);
|
162 |
+
|
163 |
+
await queryRunner.commitTransaction();
|
164 |
+
await queryRunner.release();
|
165 |
+
|
166 |
+
return { ...order, order_items: orderItems };
|
167 |
+
} catch (err) {
|
168 |
+
await queryRunner.rollbackTransaction();
|
169 |
+
await queryRunner.release();
|
170 |
+
throw err;
|
171 |
}
|
|
|
|
|
|
|
|
|
172 |
}
|
173 |
|
174 |
/**
|
|
|
177 |
async findOrderOrError(id: number) {
|
178 |
const order = await OrderEntity.findOne({
|
179 |
where: { id },
|
180 |
+
relations: [
|
181 |
+
'order_items',
|
182 |
+
'order_items.branch_menu',
|
183 |
+
'order_items.branch_menu.menu_item',
|
184 |
+
],
|
185 |
});
|
186 |
if (!order) {
|
187 |
throw new NotFoundException('Order id not found');
|
|
|
189 |
return order;
|
190 |
}
|
191 |
|
192 |
+
async updateOrder(id: number, updateOrderDto: UpdateOrderDto) {
|
193 |
+
// update vì
|
194 |
+
// Offline
|
195 |
+
// Người dùng chuyển bàn
|
196 |
+
// Người dùng thêm/xoá món
|
197 |
+
// Cập nhật trạng thái
|
198 |
+
// Cập nhật rating
|
199 |
+
// Cập nhật note
|
200 |
+
}
|
201 |
+
|
202 |
+
async updateOrderPayment(id: number, paymentId: number) {
|
203 |
const order = await this.findOrderOrError(id);
|
204 |
+
order.payment_id = paymentId; // i'm trust that paymentId existed.
|
205 |
+
order.order_status = OrderStatus.ONLINE_PAID;
|
206 |
await order.save();
|
207 |
}
|
208 |
|
209 |
+
getOrderPaginteConfig() {
|
210 |
+
const paginateConfig: PaginateConfig<OrderEntity> = {
|
211 |
+
sortableColumns: ['id', 'created_at', 'total_value'],
|
212 |
+
filterableColumns: {
|
213 |
+
order_status: [FilterOperator.EQ],
|
214 |
+
create_at: [FilterOperator.GTE, FilterOperator.LTE],
|
215 |
+
updated_at: [FilterOperator.GTE, FilterOperator.LTE],
|
216 |
+
customer_id: [FilterOperator.EQ],
|
217 |
+
branch_id: [FilterOperator.EQ],
|
218 |
+
staff_id: [FilterOperator.EQ],
|
219 |
+
table_number: [FilterOperator.EQ],
|
220 |
+
rating: [FilterOperator.EQ, FilterOperator.GTE, FilterOperator.LTE],
|
221 |
+
total_value: [
|
222 |
+
FilterOperator.EQ,
|
223 |
+
FilterOperator.GTE,
|
224 |
+
FilterOperator.LTE,
|
225 |
+
],
|
226 |
+
},
|
227 |
+
defaultSortBy: [['id', 'DESC']],
|
228 |
+
};
|
229 |
+
return paginateConfig;
|
230 |
+
}
|
231 |
+
|
232 |
+
getOrderQueryBuilder(branchId?: string) {
|
233 |
//
|
234 |
+
let queryBuilder = OrderEntity.createQueryBuilder('od')
|
235 |
+
.leftJoinAndSelect('od.order_items', 'order_items')
|
236 |
+
.leftJoinAndSelect('order_items.branch_menu', 'branch_menu')
|
237 |
+
.leftJoinAndSelect('branch_menu.menu_item', 'menu_item');
|
238 |
+
if (branchId) {
|
239 |
+
queryBuilder.andWhere('od.branch_id = :branchId', { branchId });
|
240 |
+
}
|
241 |
+
// console.log(queryBuilder.getQuery());
|
242 |
+
return queryBuilder;
|
243 |
+
}
|
244 |
+
|
245 |
+
async findAll(query: PaginateQuery, branchId?: string) {
|
246 |
+
const paginateConfig = this.getOrderPaginteConfig();
|
247 |
+
let queryBuilder = this.getOrderQueryBuilder(branchId);
|
248 |
+
if (branchId) {
|
249 |
+
queryBuilder.andWhere('od.branch_id = :branchId', { branchId });
|
250 |
+
}
|
251 |
+
return paginate(query, queryBuilder, paginateConfig);
|
252 |
+
}
|
253 |
+
|
254 |
+
async findHistory(query: PaginateQuery, userId: string, branchId?: string) {
|
255 |
+
const paginateConfig = this.getOrderPaginteConfig();
|
256 |
+
let queryBuilder = this.getOrderQueryBuilder(branchId);
|
257 |
+
queryBuilder.andWhere('od.customer_id = :userId', { userId });
|
258 |
+
return paginate(query, queryBuilder, paginateConfig);
|
259 |
}
|
260 |
|
261 |
+
async findOne(id: number) {
|
262 |
+
return this.findOrderOrError(id);
|
263 |
}
|
264 |
|
265 |
+
async remove(id: number) {
|
266 |
+
const order = await this.findOrderOrError(id);
|
267 |
+
return await OrderEntity.softRemove(order);
|
268 |
}
|
269 |
}
|