import { Body, Controller, Get, Param, Post, Res } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { Public } from 'src/core/guards'; import { TransactionDto } from './dto/booking-order.dto'; import { TransactionEntity } from 'src/modules/transaction/transaction/domain/entities/transaction.entity'; import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service'; import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; import { MidtransService } from 'src/modules/configuration/midtrans/data/services/midtrans.service'; import { CreateBookingManager } from '../domain/usecases/managers/create-booking.manager'; import * as QRCode from 'qrcode'; import { Gate } from 'src/core/response/domain/decorators/pagination.response'; import { Response } from 'express'; import { RescheduleRequestDTO, RescheduleVerificationOTP, } from './dto/reschedule.dto'; import { RescheduleVerificationManager } from '../domain/usecases/managers/reschedule-verification.manager'; @ApiTags('Booking Order') @Controller('v1/booking') @Public(true) export class BookingOrderController { constructor( private createBooking: CreateBookingManager, private serviceData: TransactionDataService, private midtransService: MidtransService, private rescheduleVerification: RescheduleVerificationManager, ) {} @Post() async create(@Body() data: TransactionDto) { const payload: Partial = data; this.createBooking.setData(payload as any); this.createBooking.setService( this.serviceData, TABLE_NAME.TRANSACTION, this.midtransService, ); await this.createBooking.execute(); const result = await this.createBooking.getResult(); const { invoice_code, status, payment_midtrans_token, payment_midtrans_url, id, } = result; return { id, invoice_code, status, payment_midtrans_token, payment_midtrans_url, }; } @Post('reschedule') async reschedule(@Body() data: RescheduleRequestDTO) { const result = await this.rescheduleVerification.saveVerification(data); const maskedPhoneNumber = result.phone_number.replace(/.(?=.{4})/g, '*'); result.phone_number = maskedPhoneNumber; return `Verification code sent to ${maskedPhoneNumber}`; } @Post('reschedule/verification') async verificationReschedule(@Body() data: RescheduleVerificationOTP) { const result = await this.rescheduleVerification.verifyOtp( data.booking_id, +data.code, ); const transaction = await this.get(data.booking_id); return { ...result, transaction }; } @Get(':id') async get(@Param('id') transactionId: string) { const data = await this.serviceData.getOneByOptions({ relations: ['items'], where: { id: transactionId }, }); const { customer_name, customer_phone, booking_date, invoice_code, status, id, items, } = data; const usageItems = items.map((item) => { const { id, item_id, item_name, item_price, item_category_name, total_price, total_net_price, qty, qty_remaining, } = item; return { id, item_id, item_name, item_price, item_category_name, total_price, total_net_price, qty, qty_remaining, }; }); // Mask customer_phone with * and keep last 4 numbers let maskedCustomerPhone = customer_phone; if (typeof customer_phone === 'string' && customer_phone.length > 4) { const last4 = customer_phone.slice(-4); maskedCustomerPhone = '*'.repeat(customer_phone.length - 4) + last4; } return { customer_name, customer_phone: maskedCustomerPhone, booking_date, invoice_code, status, id, items: usageItems, }; } @Gate() @Get('qrcode/:id') async getQRcode(@Param('id') id: string, @Res() res: Response) { console.log(QRCode); const qrData = id; const data = await QRCode.toDataURL(qrData); res.setHeader('Content-Type', 'image/png'); const base64Data = data.split(',')[1]; const buffer = Buffer.from(base64Data, 'base64'); res.send(buffer); } }