Files
psp_api/src/modules/partners/partners.service.ts
T
ahasani dee96b6e91 feat: add response DTOs for various services across modules
- Created response DTOs for ConfigService, AppService, AuthService, CatalogsService, AccountsService, BusinessActivityComplexesService, ComplexPosesService, SalesInvoicesService, BusinessActivitiesService, ConsumerBusinessActivityGoodsService, and others.
- Implemented Create, FindAll, FindOne, and Update response types for services in consumer, partners, and POS modules.
- Added request DTOs for creating and updating goods in the consumer business activities module.
- Introduced filtering DTO for partner licenses.
- Enhanced response mapping for partner license activations.
2026-04-27 10:45:39 +03:30

244 lines
6.3 KiB
TypeScript

import { UploadedFileTypes } from '@/common/enums/enums'
import { ResponseMapper } from '@/common/response/response-mapper'
import { PartnerAccountSelect } from '@/generated/prisma/models'
import { UploaderService } from '@/modules/uploader/uploader.service'
import { PrismaService } from '@/prisma/prisma.service'
import { Injectable } from '@nestjs/common'
import { UpdatePartnerProfileDto } from './dto/partner.dto'
@Injectable()
export class PartnerService {
constructor(
private readonly prisma: PrismaService,
private readonly uploaderService: UploaderService,
) {}
private readonly defaultSelect: PartnerAccountSelect = {}
async me(partner_id: string, account_id: string) {
const partner = await this.prisma.partnerAccount.findUniqueOrThrow({
where: {
id: account_id,
partner_id,
},
select: {
id: true,
role: true,
account: {
select: {
username: true,
},
},
partner: {
select: {
id: true,
name: true,
},
},
},
})
return ResponseMapper.single(partner)
}
async getInfo(partner_id: string) {
const partner = await this.prisma.partner.findUniqueOrThrow({
where: {
id: partner_id,
},
select: {
id: true,
name: true,
code: true,
logo_url: true,
created_at: true,
license_charge_transactions: {
select: {
purchased_count: true,
activation_expires_at: true,
_count: {
select: {
licenses: {
where: {
activation: {
isNot: null,
},
},
},
},
},
},
},
account_quota_charge_transactions: {
select: {
purchased_count: true,
activation_expires_at: true,
_count: {
select: {
credits: {
where: {
charge_transaction: {
isNot: null,
},
allocation: {
isNot: null,
},
},
},
},
},
},
},
license_renew_charge_transactions: {
select: {
purchased_count: true,
activation_expires_at: true,
_count: {
select: {
license_renews: {
where: {
activation: {
isNot: undefined,
},
},
},
},
},
},
},
},
})
const {
license_charge_transactions,
account_quota_charge_transactions,
license_renew_charge_transactions,
...partnerInfo
} = partner
const licenses_status = {
total_purchased: 0,
total_activated: 0,
total_expired: 0,
}
const account_quotas_status = {
total_purchased: 0,
total_activated: 0,
total_expired: 0,
}
const license_renews_status = {
total_purchased: 0,
total_activated: 0,
total_expired: 0,
}
const now = new Date()
const checkExpired = (expires_at: Date) => expires_at < now
const prepareData = (
items_count: number,
activation_expires_at: Date,
purchased_count: number,
) => {
let totalActivated = 0
let totalExpired = 0
if (!checkExpired(activation_expires_at)) {
totalActivated = items_count
} else {
totalExpired = items_count
}
return {
total_purchased: purchased_count,
total_activated: totalActivated,
total_expired: totalExpired,
}
}
license_charge_transactions.forEach(
({ _count, activation_expires_at, purchased_count }) => {
const status = prepareData(
_count.licenses,
activation_expires_at,
purchased_count,
)
licenses_status.total_purchased += status.total_purchased
licenses_status.total_activated += status.total_activated
licenses_status.total_expired += status.total_expired
},
)
account_quota_charge_transactions.forEach(
({ _count, activation_expires_at, purchased_count }) => {
const status = prepareData(_count.credits, activation_expires_at, purchased_count)
account_quotas_status.total_purchased += status.total_purchased
account_quotas_status.total_activated += status.total_activated
account_quotas_status.total_expired += status.total_expired
},
)
license_renew_charge_transactions.forEach(
({ _count, activation_expires_at, purchased_count }) => {
const status = prepareData(
_count.license_renews,
activation_expires_at,
purchased_count,
)
license_renews_status.total_purchased += status.total_purchased
license_renews_status.total_activated += status.total_activated
license_renews_status.total_expired += status.total_expired
},
)
return ResponseMapper.single({
licenses_status,
license_renews_status,
account_quotas_status,
...partnerInfo,
})
}
async updateInfo(
partner_id: string,
data: UpdatePartnerProfileDto,
logo?: Express.Multer.File,
) {
const rest = { ...(data as any) }
delete rest.logo
const updatedPartner = 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: partner_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: partner_id,
},
data: {
...rest,
...(logo_url ? { logo_url } : {}),
},
select: this.defaultSelect,
})
})
return ResponseMapper.single(updatedPartner)
}
}