import { PasswordUtil } from '@/common/utils/password.util' import { AccountStatus, AccountType, ConsumerRole, ConsumerStatus, PartnerStatus, } from '@/generated/prisma/enums' import { ConsumerSelect, ConsumerWhereInput } from '@/generated/prisma/models' import mapConsumerWithLicenseUtil from '@/modules/consumer/utils/mapConsumerWithLicense.util' import { PrismaService } from '@/prisma/prisma.service' import { BadRequestException, Injectable } from '@nestjs/common' import { ResponseMapper } from 'common/response/response-mapper' import { CreateConsumerDto, UpdateConsumerDto } from './dto/create-consumers.dto' @Injectable() export class PartnerConsumersService { constructor(private readonly prisma: PrismaService) {} private readonly setExpireDate = (starts_at: Date) => { return new Date( new Date(starts_at).setFullYear(new Date(starts_at).getFullYear() + 1), ).toISOString() } defaultSelect: ConsumerSelect = { id: true, first_name: true, last_name: true, mobile_number: true, national_code: true, status: true, created_at: true, } private defaultWhere = (partner_id: string): ConsumerWhereInput => ({ partner_id, }) async findAll(partner_id: string, page = 1, perPage = 10) { const [consumers, total] = await this.prisma.$transaction(async tx => [ await tx.consumer.findMany({ where: this.defaultWhere(partner_id), select: this.defaultSelect, skip: (page - 1) * perPage, take: 10, }), await tx.consumer.count({ where: this.defaultWhere(partner_id), }), ]) return ResponseMapper.paginate(consumers.map(mapConsumerWithLicenseUtil), { total, page, perPage, }) } async findOne(partner_id: string, consumer_id: string) { const consumer = await this.prisma.consumer.findUniqueOrThrow({ where: { ...(this.defaultWhere(partner_id) as any), id: consumer_id, }, select: this.defaultSelect, }) return ResponseMapper.single(mapConsumerWithLicenseUtil(consumer)) } async create(partner_id: string, data: CreateConsumerDto) { const consumer = await this.prisma.$transaction(async tx => { const partnerLicense = await tx.license.findFirst({ where: { charge_transaction: { partner: { id: partner_id, status: PartnerStatus.ACTIVE, }, }, activation: null, }, orderBy: { charge_transaction: { activation_expires_at: 'asc', }, }, select: { id: true, charge_transaction: { select: { partner: { select: { id: true, name: true, status: true, }, }, }, }, }, }) if (!partnerLicense) { throw new BadRequestException(`تعداد لایسنس‌های فعلی شما به پایان رسیده است.`) } const { username, password, license_starts_at, ...rest } = data const existingConsumer = await tx.consumer.findFirst({ where: { partner_id, OR: [ { mobile_number: data.mobile_number }, { national_code: data.national_code }, ], }, select: { id: true, first_name: true, last_name: true }, }) if (existingConsumer) { throw new BadRequestException( `مصرف کننده‌ی ${existingConsumer.first_name} ${existingConsumer.last_name} با شماره موبایل یا کد ملی وارد شده از قبل ثبت شده است.`, ) } return await tx.consumer.create({ data: { ...rest, partner: { connect: { id: partner_id, }, }, consumer_accounts: { create: { role: ConsumerRole.OWNER, account: { create: { username, password: await PasswordUtil.hash(password), type: AccountType.CONSUMER, status: AccountStatus.ACTIVE, }, }, }, }, status: ConsumerStatus.ACTIVE, }, select: this.defaultSelect, }) }) return ResponseMapper.single(mapConsumerWithLicenseUtil(consumer)) } async update(id: string, partner_id: string, data: UpdateConsumerDto) { return this.prisma.consumer.update({ where: { ...(this.defaultWhere(partner_id) as any), id, }, data, }) } }