import { QUERY_CONSTANTS } from '@/common/queryConstants' import { RedisKeyMaker } from '@/common/utils' import { ComplexSelect, ComplexWhereInput } from '@/generated/prisma/models' import { PartnersCacheInvalidationService } from '@/modules/partners/cache/partners-cache-invalidation.service' import { PrismaService } from '@/prisma/prisma.service' import { RedisService } from '@/redis/redis.service' import { BadRequestException, Injectable } from '@nestjs/common' import { ResponseMapper } from 'common/response/response-mapper' import { CreateComplexDto, UpdateComplexDto } from './dto/complex.dto' @Injectable() export class BusinessActivityComplexesService { constructor( private readonly prisma: PrismaService, private readonly redisService: RedisService, private readonly partnersCacheInvalidationService: PartnersCacheInvalidationService, ) {} private readonly cacheTtlSeconds = 300 private readonly defaultSelect: ComplexSelect = { id: true, name: true, address: true, branch_code: true, created_at: true, } private readonly defaultWhere = ( partner_id, consumer_id, business_activity_id, ): ComplexWhereInput => ({ business_activity: { id: business_activity_id, consumer: { id: consumer_id, OR: [ { legal: { partner_id, }, }, { individual: { partner_id, }, }, ], }, }, }) async findAll( partner_id: string, consumer_id: string, business_activity_id: string, page = 1, perPage = 10, ) { const cacheKey = RedisKeyMaker.partnerConsumerBusinessActivityComplexesList( partner_id, consumer_id, business_activity_id, page, perPage, ) const cached = await this.redisService.getJson<{ items: unknown[]; total: number }>( cacheKey, ) if (cached) { return ResponseMapper.paginate(cached.items, { total: cached.total, page, perPage }) } const where = this.defaultWhere(partner_id, consumer_id, business_activity_id) const [complexes, total] = await this.prisma.$transaction(async tx => [ await tx.complex.findMany({ where, select: { ...this.defaultSelect, _count: { select: { pos_list: true, }, }, }, skip: (page - 1) * perPage, take: perPage, }), await tx.complex.count({ where }), ]) const mappedComplexes = complexes.map(complex => { const { _count, ...rest } = complex return { ...rest, pos_count: _count.pos_list, } }) await this.redisService.setJson( cacheKey, { items: mappedComplexes, total }, this.cacheTtlSeconds, ) return ResponseMapper.paginate(mappedComplexes, { total, page, perPage }) } async findOne( partner_id: string, consumer_id: string, business_activity_id: string, id: string, ) { const cacheKey = RedisKeyMaker.partnerConsumerBusinessActivityComplexInfo( partner_id, consumer_id, business_activity_id, id, ) const cached = await this.redisService.getJson(cacheKey) if (cached) { return ResponseMapper.single(cached) } const complex = await this.prisma.complex.findFirst({ where: { ...this.defaultWhere(partner_id, consumer_id, business_activity_id), id, }, select: this.defaultSelect, }) if (!complex) { throw new BadRequestException('شعبه مورد نظر یافت نشد.') } await this.redisService.setJson(cacheKey, complex, this.cacheTtlSeconds) return ResponseMapper.single(complex) } async create( partner_id: string, business_id: string, consumer_id: string, data: CreateComplexDto, ) { const complex = await this.prisma.$transaction(async tx => { const relatedLicense = await tx.licenseAccountAllocation.findFirst({ where: { license_activation: { license: { charge_transaction: { partner_id, }, }, business_activity: { id: business_id, }, ...QUERY_CONSTANTS.LICENSE_ACTIVATION.activeOnDate(), }, account_id: null, }, select: { id: true, }, }) if (!relatedLicense) { throw new BadRequestException( `متاسفانه به دلیل به پایان رسیدن محدودیت تعریف کاربران برای این فعالیت اقتصادی،‌امکان ایجاد شعبه‌ی جدید وجود ندارد.`, ) } return await tx.complex.create({ data: { ...data, business_activity: { connect: { id: business_id, }, }, }, }) }) await this.partnersCacheInvalidationService.invalidatePartnerConsumerBusinessActivityComplexesReadModels( partner_id, consumer_id, business_id, ) return ResponseMapper.create(complex) } async update( partner_id: string, consumer_id: string, business_activity_id: string, id: string, data: UpdateComplexDto, ) { const complex = await this.prisma.complex.update({ where: { ...this.defaultWhere(partner_id, consumer_id, business_activity_id), id }, data, }) await this.partnersCacheInvalidationService.invalidatePartnerConsumerBusinessActivityComplexReadModels( partner_id, consumer_id, business_activity_id, id, ) return ResponseMapper.update(complex) } // async delete(id: string) { // await this.prisma.complex.delete({ where: { id } }) // return ResponseMapper.delete() // } }