feat(partners): add utility functions for partner business activity allocation limits and remaining licenses

- Implemented `getPartnerBusinessActivityAllocationLimits` to retrieve allocation limits for a partner's business activity.
- Added `ensurePartnerBusinessActivityHasRemainingAllocation` to validate remaining allocation credits.
- Created `getPartnerRemainingLicenses` to count remaining licenses for a partner.
- Developed `getPartnerFirstRemainingLicense` to fetch the first unused license for a partner.
- Introduced `ensurePartnerHasRemainingLicense` to ensure a partner has at least one unused license.
This commit is contained in:
2026-04-24 23:02:05 +03:30
parent 9b652a3603
commit 12506de863
43 changed files with 4645 additions and 2196 deletions
@@ -0,0 +1,94 @@
import { BadRequestException } from '@nestjs/common'
type PartnerRemainingLicensesClient = {
license: {
count: (args: any) => Promise<number>
findFirst: (args: any) => Promise<any>
}
}
type GetPartnerRemainingLicensesParams = {
partner_id: string
referenceDate?: Date
}
export const getPartnerRemainingLicenses = async (
prisma: PartnerRemainingLicensesClient,
params: GetPartnerRemainingLicensesParams,
) => {
const { partner_id, referenceDate = new Date() } = params
const startOfDay = new Date(referenceDate)
startOfDay.setHours(0, 0, 0, 0)
const remaining_count = await prisma.license.count({
where: {
activation: null,
charge_transaction: {
partner_id,
activation_expires_at: {
gte: startOfDay,
},
},
},
})
return {
remaining_count,
}
}
export const getPartnerFirstRemainingLicense = async (
prisma: PartnerRemainingLicensesClient,
params: GetPartnerRemainingLicensesParams,
) => {
const { partner_id, referenceDate = new Date() } = params
const startOfDay = new Date(referenceDate)
startOfDay.setHours(0, 0, 0, 0)
const license = await prisma.license.findFirst({
where: {
activation: null,
charge_transaction: {
partner_id,
activation_expires_at: {
gte: startOfDay,
},
},
},
orderBy: {
charge_transaction: {
activation_expires_at: 'asc',
},
},
select: {
id: true,
charge_transaction_id: true,
accounts_limit: true,
},
})
if (!license) {
throw new BadRequestException(
'لایسنس فعال و استفاده نشده برای این شریک تجاری وجود ندارد.',
)
}
return license
}
export const ensurePartnerHasRemainingLicense = async (
prisma: PartnerRemainingLicensesClient,
params: GetPartnerRemainingLicensesParams,
) => {
const quota = await getPartnerRemainingLicenses(prisma, params)
if (quota.remaining_count <= 0) {
throw new BadRequestException(
'لایسنس فعال و استفاده نشده برای این شریک تجاری وجود ندارد.',
)
}
return quota
}