62b659246f
- Added Redis caching to BusinessActivitiesService for findAll and findOne methods. - Integrated Redis caching in BusinessActivityComplexesService for findAll and findOne methods. - Enhanced ConsumersService with Redis caching for findAll and findOne methods. - Introduced cache invalidation for partner consumers and business activities. - Created RedisKeyMaker utility for generating cache keys for consumers, partners, and POS. - Implemented cache invalidation services for partners and POS. - Added Redis service methods for JSON handling and key deletion by patterns. - Updated goods service to include caching and invalidation for goods list. - Introduced DTO for updating goods.
262 lines
7.7 KiB
TypeScript
262 lines
7.7 KiB
TypeScript
import { UploadedFileTypes } from '@/common/enums/enums'
|
|
import { translateEnumValue } from '@/common/utils'
|
|
import { PasswordUtil } from '@/common/utils/password.util'
|
|
import { RedisKeyMaker } from '@/common/utils/redisKeyMaker'
|
|
import {
|
|
AccountStatus,
|
|
AccountType,
|
|
PartnerRole,
|
|
PartnerStatus,
|
|
} from '@/generated/prisma/enums'
|
|
import { PartnerSelect } from '@/generated/prisma/models'
|
|
import { PartnersCacheInvalidationService } from '@/modules/partners/cache/partners-cache-invalidation.service'
|
|
import { UploaderService } from '@/modules/uploader/uploader.service'
|
|
import { PrismaService } from '@/prisma/prisma.service'
|
|
import { RedisService } from '@/redis/redis.service'
|
|
import { Injectable } from '@nestjs/common'
|
|
import { ResponseMapper } from 'common/response/response-mapper'
|
|
import { CreatePartnerDto, UpdatePartnerDto } from './dto/partner.dto'
|
|
|
|
@Injectable()
|
|
export class PartnersService {
|
|
private now = new Date().getTime()
|
|
constructor(
|
|
private readonly prisma: PrismaService,
|
|
private readonly uploaderService: UploaderService,
|
|
private readonly redisService: RedisService,
|
|
private readonly cacheInvalidationService: PartnersCacheInvalidationService,
|
|
) {}
|
|
|
|
private readonly defaultSelect: PartnerSelect = {
|
|
id: true,
|
|
name: true,
|
|
code: true,
|
|
status: true,
|
|
logo_url: true,
|
|
tsp_provider: true,
|
|
created_at: true,
|
|
license_charge_transactions: {
|
|
select: {
|
|
activation_expires_at: true,
|
|
purchased_count: true,
|
|
_count: {
|
|
select: {
|
|
licenses: {
|
|
where: {
|
|
activation: {
|
|
isNot: null,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
license_renew_charge_transactions: {
|
|
select: {
|
|
activation_expires_at: true,
|
|
purchased_count: true,
|
|
_count: {
|
|
select: {
|
|
license_renews: {
|
|
where: {
|
|
activation: {
|
|
isNot: undefined,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
account_quota_charge_transactions: {
|
|
select: {
|
|
activation_expires_at: true,
|
|
purchased_count: true,
|
|
_count: {
|
|
select: {
|
|
credits: {
|
|
where: {
|
|
allocation: {
|
|
isNot: null,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
private readonly mapPartner = (partner: any) => {
|
|
const {
|
|
license_charge_transactions,
|
|
account_quota_charge_transactions,
|
|
license_renew_charge_transactions,
|
|
status,
|
|
...rest
|
|
} = partner
|
|
|
|
const account_quota_status = { total: 0, used: 0, expired: 0 }
|
|
account_quota_charge_transactions.forEach((account_quota_charge_transaction: any) => {
|
|
const total = account_quota_charge_transaction.purchased_count
|
|
const used = account_quota_charge_transaction._count.credits
|
|
account_quota_status.total += total
|
|
account_quota_status.used += used
|
|
account_quota_status.expired +=
|
|
account_quota_charge_transaction.activation_expires_at.getTime() <= this.now
|
|
? total - used
|
|
: 0
|
|
})
|
|
|
|
const licenses_status = { total: 0, used: 0, expired: 0 }
|
|
license_charge_transactions.forEach((license_charge_transaction: any) => {
|
|
const total = license_charge_transaction.purchased_count
|
|
const used = license_charge_transaction._count.licenses
|
|
licenses_status.total += total
|
|
licenses_status.used += used
|
|
licenses_status.expired +=
|
|
license_charge_transaction.activation_expires_at.getTime() <= this.now
|
|
? total - used
|
|
: 0
|
|
})
|
|
|
|
const license_renew_status = { total: 0, used: 0, expired: 0 }
|
|
license_renew_charge_transactions.forEach((license_renew_charge_transaction: any) => {
|
|
const total = license_renew_charge_transaction.purchased_count
|
|
const used = license_renew_charge_transaction._count.license_renews
|
|
license_renew_status.total += total
|
|
license_renew_status.used += used
|
|
license_renew_status.expired +=
|
|
license_renew_charge_transaction.activation_expires_at.getTime() <= this.now
|
|
? total - used
|
|
: 0
|
|
})
|
|
return {
|
|
...rest,
|
|
status: translateEnumValue('PartnerStatus', status),
|
|
licenses_status,
|
|
license_renew_status,
|
|
account_quota_status,
|
|
}
|
|
}
|
|
|
|
async findAll() {
|
|
const cacheKey = RedisKeyMaker.partnersList()
|
|
const cached = await this.redisService.getJson<unknown[]>(cacheKey)
|
|
if (cached) {
|
|
console.log('cached', cached)
|
|
|
|
return ResponseMapper.list(cached)
|
|
}
|
|
|
|
const partners = await this.prisma.partner.findMany({
|
|
select: this.defaultSelect,
|
|
})
|
|
|
|
const mappedPartners = partners.map(this.mapPartner)
|
|
await this.redisService.setJson(cacheKey, mappedPartners, 300)
|
|
|
|
return ResponseMapper.list(mappedPartners)
|
|
}
|
|
|
|
async findOne(id: string) {
|
|
const cacheKey = RedisKeyMaker.partnerDetail(id)
|
|
const cached = await this.redisService.getJson<unknown>(cacheKey)
|
|
if (cached) {
|
|
return ResponseMapper.single(cached)
|
|
}
|
|
|
|
const partner = await this.prisma.partner.findUniqueOrThrow({
|
|
where: { id },
|
|
select: this.defaultSelect,
|
|
})
|
|
|
|
const mappedPartner = this.mapPartner(partner)
|
|
await this.redisService.setJson(cacheKey, mappedPartner, 300)
|
|
|
|
return ResponseMapper.single(mappedPartner)
|
|
}
|
|
|
|
async create(data: CreatePartnerDto, logo?: any) {
|
|
const { username, password, ...rest } = data as any
|
|
delete rest.logo
|
|
|
|
const logo_url = logo
|
|
? await this.uploaderService.uploadFile(logo, UploadedFileTypes.PARTNER_LOGO)
|
|
: undefined
|
|
|
|
const partner = await this.prisma.partner.create({
|
|
data: {
|
|
...rest,
|
|
status: PartnerStatus.ACTIVE,
|
|
...(logo_url ? { logo_url } : {}),
|
|
accounts: {
|
|
create: {
|
|
role: PartnerRole.OWNER,
|
|
account: {
|
|
create: {
|
|
username,
|
|
password: await PasswordUtil.hash(password),
|
|
status: AccountStatus.ACTIVE,
|
|
type: AccountType.PARTNER,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
select: this.defaultSelect,
|
|
})
|
|
await this.cacheInvalidationService.invalidatePartnersList()
|
|
await this.cacheInvalidationService.invalidatePartnerDetail(partner.id)
|
|
return ResponseMapper.create(partner)
|
|
}
|
|
|
|
async update(id: string, data: UpdatePartnerDto, logo?: any) {
|
|
const rest = { ...(data as any) }
|
|
delete rest.logo
|
|
|
|
const partner = await this.prisma.$transaction(async tx => {
|
|
let logo_url = ''
|
|
if (logo) {
|
|
const uploadedUrl = await this.uploaderService.uploadFile(
|
|
logo,
|
|
UploadedFileTypes.PARTNER_LOGO,
|
|
)
|
|
logo_url = uploadedUrl || ''
|
|
}
|
|
|
|
const prevLogo = await tx.partner.findUnique({
|
|
where: { id },
|
|
select: { logo_url: true },
|
|
})
|
|
|
|
if (logo_url && prevLogo?.logo_url) {
|
|
this.uploaderService.deleteFile(prevLogo.logo_url, UploadedFileTypes.PARTNER_LOGO)
|
|
}
|
|
|
|
return tx.partner.update({
|
|
where: { id },
|
|
data: {
|
|
...rest,
|
|
...(logo_url ? { logo_url } : {}),
|
|
},
|
|
select: this.defaultSelect,
|
|
})
|
|
})
|
|
|
|
await this.cacheInvalidationService.invalidatePartnersList()
|
|
await this.cacheInvalidationService.invalidatePartnerDetail(id)
|
|
|
|
return ResponseMapper.update(partner)
|
|
}
|
|
|
|
async delete(id: string) {
|
|
await this.prisma.partner.delete({ where: { id } })
|
|
await this.cacheInvalidationService.invalidatePartnersList()
|
|
await this.cacheInvalidationService.invalidatePartnerDetail(id)
|
|
await this.cacheInvalidationService.invalidatePartnerLicenses(id)
|
|
return ResponseMapper.delete()
|
|
}
|
|
}
|