add cancellationReason
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AddBookingCancellationReason1789046800000
|
||||||
|
implements MigrationInterface
|
||||||
|
{
|
||||||
|
name = 'AddBookingCancellationReason1789046800000';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE "bookings"
|
||||||
|
ADD COLUMN IF NOT EXISTS "cancellationReason" text
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE "bookings"
|
||||||
|
DROP COLUMN IF EXISTS "cancellationReason"
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,6 +66,9 @@ export class BookingEntity {
|
|||||||
@Column({ type: 'text', nullable: true })
|
@Column({ type: 'text', nullable: true })
|
||||||
note!: string | null;
|
note!: string | null;
|
||||||
|
|
||||||
|
@Column({ type: 'text', nullable: true })
|
||||||
|
cancellationReason!: string | null;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Date;
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { RolesGuard } from '../auth/guards/roles.guard';
|
|||||||
import { BookingsService } from './bookings.service';
|
import { BookingsService } from './bookings.service';
|
||||||
import { CreateBookingDto } from './dto/create-booking.dto';
|
import { CreateBookingDto } from './dto/create-booking.dto';
|
||||||
import { CreateBookingBatchDto } from './dto/create-booking-batch.dto';
|
import { CreateBookingBatchDto } from './dto/create-booking-batch.dto';
|
||||||
|
import { CancelBookingDto } from './dto/cancel-booking.dto';
|
||||||
import { UpdateBookingDto } from './dto/update-booking.dto';
|
import { UpdateBookingDto } from './dto/update-booking.dto';
|
||||||
|
|
||||||
@Controller('bookings')
|
@Controller('bookings')
|
||||||
@@ -128,9 +129,10 @@ export class BookingsController {
|
|||||||
@Roles(UserRole.ADMIN, UserRole.BUSINESS_OWNER, UserRole.CUSTOMER)
|
@Roles(UserRole.ADMIN, UserRole.BUSINESS_OWNER, UserRole.CUSTOMER)
|
||||||
cancel(
|
cancel(
|
||||||
@Param('id') id: string,
|
@Param('id') id: string,
|
||||||
|
@Body() payload: CancelBookingDto,
|
||||||
@CurrentUser() user: AuthUser,
|
@CurrentUser() user: AuthUser,
|
||||||
): Promise<BookingEntity> {
|
): Promise<BookingEntity> {
|
||||||
return this.service.cancel(id, user);
|
return this.service.cancel(id, user, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
|
|||||||
@@ -324,9 +324,22 @@ export class BookingsService {
|
|||||||
return this.repo.save(row);
|
return this.repo.save(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
async cancel(id: string, actor?: AuthUser): Promise<BookingEntity> {
|
async cancel(
|
||||||
|
id: string,
|
||||||
|
actor?: AuthUser,
|
||||||
|
payload?: { cancellationReason?: string },
|
||||||
|
): Promise<BookingEntity> {
|
||||||
const row = await this.findOne(id);
|
const row = await this.findOne(id);
|
||||||
this.assertCanCancelBooking(row, actor);
|
this.assertCanCancelBooking(row, actor);
|
||||||
|
|
||||||
|
const reason = payload?.cancellationReason?.trim() ?? '';
|
||||||
|
if (actor?.role === UserRole.BUSINESS_OWNER && !reason) {
|
||||||
|
throw new BadRequestException('Cancellation reason is required');
|
||||||
|
}
|
||||||
|
if (reason) {
|
||||||
|
row.cancellationReason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
this.applyStatusTransition(row, BookingStatus.CANCELLED, actor);
|
this.applyStatusTransition(row, BookingStatus.CANCELLED, actor);
|
||||||
return this.repo.save(row);
|
return this.repo.save(row);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { IsOptional, IsString, MaxLength } from 'class-validator';
|
||||||
|
|
||||||
|
export class CancelBookingDto {
|
||||||
|
@ApiPropertyOptional({ example: 'ظرفیت این بازه تکمیل شده است.' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(500)
|
||||||
|
cancellationReason?: string;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user