list of card to card
This commit is contained in:
@@ -27,6 +27,8 @@ import { SalonSubscriptionsService } from '../subscriptions/salon-subscriptions.
|
||||
import { UploaderService } from '../uploader/uploader.service';
|
||||
import { UserRole } from '../users/enums/user-role.enum';
|
||||
import { ShortLinksService } from '../short-links/short-links.service';
|
||||
import { DepositListItemDto } from './dto/deposit-list-item.dto';
|
||||
import { FindDepositsQueryDto } from './dto/find-deposits-query.dto';
|
||||
import { PublicDepositPaymentDto } from './dto/public-deposit-payment.dto';
|
||||
import { ReviewDepositDto } from './dto/review-deposit.dto';
|
||||
import { Payment } from './entities/payment.entity';
|
||||
@@ -253,6 +255,43 @@ export class CardToCardDepositService {
|
||||
return this.getPublicPaymentByToken(token);
|
||||
}
|
||||
|
||||
async findForSalon(
|
||||
user: AuthUser,
|
||||
query: FindDepositsQueryDto,
|
||||
): Promise<DepositListItemDto[]> {
|
||||
if (user.role !== UserRole.SALON && user.role !== UserRole.ADMIN) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
const qb = this.paymentsRepository
|
||||
.createQueryBuilder('payment')
|
||||
.innerJoinAndSelect('payment.reserve', 'reserve')
|
||||
.innerJoinAndSelect('reserve.salon', 'salon')
|
||||
.leftJoinAndSelect('reserve.customer', 'customer')
|
||||
.leftJoinAndSelect('customer.user', 'customerUser')
|
||||
.where('payment.type = :type', { type: PaymentType.DEPOSIT })
|
||||
.andWhere('payment.method = :method', {
|
||||
method: PaymentMethod.CARD_TO_CARD,
|
||||
})
|
||||
.orderBy('payment.createdAt', 'DESC');
|
||||
|
||||
if (query.status) {
|
||||
qb.andWhere('payment.status = :status', { status: query.status });
|
||||
}
|
||||
|
||||
if (!this.authorizationService.isAdmin(user)) {
|
||||
qb.andWhere('salon.ownerId = :ownerId', { ownerId: user.id });
|
||||
}
|
||||
|
||||
const limit = query.limit ?? 50;
|
||||
const offset = query.offset ?? 0;
|
||||
qb.take(limit).skip(offset);
|
||||
|
||||
const payments = await qb.getMany();
|
||||
|
||||
return payments.map((payment) => this.toDepositListItem(payment));
|
||||
}
|
||||
|
||||
async findForReview(paymentId: string, user: AuthUser): Promise<Payment> {
|
||||
const payment = await this.loadPaymentWithRelations(paymentId);
|
||||
this.assertCanReview(user, payment);
|
||||
@@ -391,4 +430,23 @@ export class CardToCardDepositService {
|
||||
private rialToToman(amountRial: number): number {
|
||||
return Math.round(amountRial / 10);
|
||||
}
|
||||
|
||||
private toDepositListItem(payment: Payment): DepositListItemDto {
|
||||
const user = payment.reserve?.customer?.user;
|
||||
const customerName = user
|
||||
? `${user.firstName} ${user.lastName}`.trim()
|
||||
: 'مشتری';
|
||||
|
||||
return {
|
||||
id: payment.id,
|
||||
status: payment.status,
|
||||
amountToman: this.rialToToman(payment.amountRial),
|
||||
receiptUrl: payment.receiptUrl,
|
||||
createdAt: payment.createdAt,
|
||||
customerName,
|
||||
customerMobile: user?.mobile ?? null,
|
||||
appointmentDate: payment.reserve?.appointmentDate ?? null,
|
||||
startTime: payment.reserve?.startTime ?? null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
Param,
|
||||
ParseUUIDPipe,
|
||||
Post,
|
||||
Query,
|
||||
UploadedFile,
|
||||
UseGuards,
|
||||
UseInterceptors,
|
||||
@@ -25,6 +26,8 @@ import { ApiPublicEndpoint } from '../swagger/decorators/swagger-auth.decorator'
|
||||
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||
import { UserRole } from '../users/enums/user-role.enum';
|
||||
import { CardToCardDepositService } from './card-to-card-deposit.service';
|
||||
import { DepositListItemDto } from './dto/deposit-list-item.dto';
|
||||
import { FindDepositsQueryDto } from './dto/find-deposits-query.dto';
|
||||
import { PublicDepositPaymentDto } from './dto/public-deposit-payment.dto';
|
||||
import { ReviewDepositDto } from './dto/review-deposit.dto';
|
||||
import { Payment } from './entities/payment.entity';
|
||||
@@ -84,6 +87,18 @@ export class DepositsController {
|
||||
return this.cardToCardDepositService.submitReceipt(token, file);
|
||||
}
|
||||
|
||||
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||
@UseGuards(RolesGuard)
|
||||
@Roles(UserRole.ADMIN, UserRole.SALON)
|
||||
@ApiStandardOkResponse(DepositListItemDto, { isArray: true })
|
||||
@Get()
|
||||
findAll(
|
||||
@Query() query: FindDepositsQueryDto,
|
||||
@CurrentUser() user: AuthUser,
|
||||
) {
|
||||
return this.cardToCardDepositService.findForSalon(user, query);
|
||||
}
|
||||
|
||||
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||
@UseGuards(RolesGuard)
|
||||
@Roles(UserRole.ADMIN, UserRole.SALON)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { PaymentStatus } from '../enums/payment-status.enum';
|
||||
|
||||
export class DepositListItemDto {
|
||||
@ApiProperty()
|
||||
id: string;
|
||||
|
||||
@ApiProperty({ enum: PaymentStatus })
|
||||
status: PaymentStatus;
|
||||
|
||||
@ApiProperty({ example: 500000 })
|
||||
amountToman: number;
|
||||
|
||||
@ApiProperty({ required: false, nullable: true })
|
||||
receiptUrl: string | null;
|
||||
|
||||
@ApiProperty()
|
||||
createdAt: Date;
|
||||
|
||||
@ApiProperty({ example: 'مریم احمدی' })
|
||||
customerName: string;
|
||||
|
||||
@ApiProperty({ required: false, nullable: true, example: '09121234567' })
|
||||
customerMobile: string | null;
|
||||
|
||||
@ApiProperty({ required: false, nullable: true })
|
||||
appointmentDate: string | null;
|
||||
|
||||
@ApiProperty({ required: false, nullable: true })
|
||||
startTime: string | null;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsEnum, IsInt, IsOptional, Max, Min } from 'class-validator';
|
||||
import { PaymentStatus } from '../enums/payment-status.enum';
|
||||
|
||||
export class FindDepositsQueryDto {
|
||||
@IsOptional()
|
||||
@IsEnum(PaymentStatus)
|
||||
status?: PaymentStatus;
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
@Max(100)
|
||||
limit?: number;
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
@Min(0)
|
||||
offset?: number;
|
||||
}
|
||||
Reference in New Issue
Block a user