feat: refactor ComplexPosesService to remove unused defaultInsert method and improve findAll logic
fix: update PartnersService to use 'isNot' instead of 'not' for allocation checks refactor: enhance BusinessActivityComplexesService to validate license activation before creating a complex fix: adjust ComplexPosesService to ensure account allocation checks are accurate and handle errors properly refactor: modify ConsumerMiddleware to set consumerData instead of partnerData for better clarity feat: expand SaleInvoicesService to include additional fields in the invoice selection chore: update business-activities module to include accounts-charge module for better organization fix: ensure ComplexPosesService correctly handles account allocation during POS creation feat: implement PartnerBusinessActivityAccountsCharge module with create functionality for account charges refactor: streamline getPartnerBusinessActivityAllocationLimits utility for better clarity and functionality chore: add migration script to update database schema with necessary constraints and foreign keys feat: create DTO for accounts charge to validate incoming data
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import { PosCreateInput, PosSelect } from '@/generated/prisma/models'
|
||||
import { PosSelect } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { CreatePosDto } from './dto/pos.dto'
|
||||
|
||||
@Injectable()
|
||||
export class ComplexPosesService {
|
||||
@@ -49,32 +48,32 @@ export class ComplexPosesService {
|
||||
},
|
||||
} as PosSelect
|
||||
|
||||
defaultInsert = (data: CreatePosDto, complex_id: string) => {
|
||||
const { device_id, provider_id, ...rest } = data
|
||||
// defaultInsert = (data: CreatePosDto, complex_id: string) => {
|
||||
// const { device_id, provider_id, ...rest } = data
|
||||
|
||||
return {
|
||||
...rest,
|
||||
complex: {
|
||||
connect: {
|
||||
id: complex_id,
|
||||
},
|
||||
},
|
||||
provider: provider_id
|
||||
? {
|
||||
connect: {
|
||||
id: provider_id,
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
device: device_id
|
||||
? {
|
||||
connect: {
|
||||
id: device_id,
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
} as PosCreateInput
|
||||
}
|
||||
// return {
|
||||
// ...rest,
|
||||
// complex: {
|
||||
// connect: {
|
||||
// id: complex_id,
|
||||
// },
|
||||
// },
|
||||
// provider: provider_id
|
||||
// ? {
|
||||
// connect: {
|
||||
// id: provider_id,
|
||||
// },
|
||||
// }
|
||||
// : undefined,
|
||||
// device: device_id
|
||||
// ? {
|
||||
// connect: {
|
||||
// id: device_id,
|
||||
// },
|
||||
// }
|
||||
// : undefined,
|
||||
// } as PosCreateInput
|
||||
// }
|
||||
|
||||
async findAll(business_activity_id: string, complex_id: string) {
|
||||
const accounts = await this.prisma.pos.findMany({
|
||||
|
||||
@@ -64,8 +64,8 @@ export class PartnersService {
|
||||
select: {
|
||||
credits: {
|
||||
where: {
|
||||
allocation_id: {
|
||||
not: null,
|
||||
allocation: {
|
||||
isNot: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -2,7 +2,6 @@ import { ComplexSelect } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { BadRequestException, Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { getBusinessActivityRemainingAccounts } from '../../utils/getBusinessActivityRemainingAccounts.util'
|
||||
import { CreateConsumerComplexDto, UpdateConsumerComplexDto } from './dto/complex.dto'
|
||||
|
||||
@Injectable()
|
||||
@@ -54,12 +53,40 @@ export class BusinessActivityComplexesService {
|
||||
data: CreateConsumerComplexDto,
|
||||
) {
|
||||
const complex = await this.prisma.$transaction(async tx => {
|
||||
const quota = await getBusinessActivityRemainingAccounts(tx, {
|
||||
consumer_id,
|
||||
business_activity_id,
|
||||
const now = new Date()
|
||||
|
||||
const relatedLicense = await tx.licenseAccountAllocation.findFirst({
|
||||
where: {
|
||||
license_activation: {
|
||||
business_activity: {
|
||||
id: business_activity_id,
|
||||
consumer_id,
|
||||
},
|
||||
OR: [
|
||||
{
|
||||
expires_at: {
|
||||
gte: now,
|
||||
},
|
||||
},
|
||||
{
|
||||
license_renews: {
|
||||
some: {
|
||||
expires_at: {
|
||||
gte: now,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
account_id: null,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (quota.remaining_accounts <= 0) {
|
||||
if (!relatedLicense) {
|
||||
throw new BadRequestException(
|
||||
`متاسفانه به دلیل به پایان رسیدن محدودیت تعریف کاربران برای این فعالیت اقتصادی،امکان ایجاد شعبهی جدید وجود ندارد.`,
|
||||
)
|
||||
|
||||
@@ -94,6 +94,7 @@ export class ComplexPosesService {
|
||||
id: complex_id,
|
||||
},
|
||||
},
|
||||
|
||||
account: {
|
||||
create: {
|
||||
role: ConsumerRole.OPERATOR,
|
||||
|
||||
@@ -44,7 +44,7 @@ export class ConsumerMiddleware implements NestMiddleware {
|
||||
return doForbidden()
|
||||
}
|
||||
|
||||
req.partnerData = {
|
||||
req.consumerData = {
|
||||
account_id: consumerAccount.id,
|
||||
id: consumerAccount.consumer_id,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
SalesInvoiceSelect,
|
||||
SalesInvoiceWhereInput,
|
||||
SalesInvoiceWhereUniqueInput,
|
||||
} from '@/generated/prisma/models'
|
||||
@@ -10,12 +11,12 @@ import { ResponseMapper } from 'common/response/response-mapper'
|
||||
export class SaleInvoicesService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
private readonly defaultSelect = {
|
||||
private readonly defaultSelect: SalesInvoiceSelect = {
|
||||
id: true,
|
||||
code: true,
|
||||
total_amount: true,
|
||||
unknown_customer: true,
|
||||
invoice_date: true,
|
||||
created_at: true,
|
||||
consumer_account: {
|
||||
select: {
|
||||
role: true,
|
||||
@@ -44,24 +45,6 @@ export class SaleInvoicesService {
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
customer: {
|
||||
select: {
|
||||
id: true,
|
||||
type: true,
|
||||
customer_legal: {
|
||||
select: {
|
||||
company_name: true,
|
||||
},
|
||||
},
|
||||
customer_individual: {
|
||||
select: {
|
||||
first_name: true,
|
||||
last_name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
async findAll(consumer_id: string, page = 1, pageSize = 10) {
|
||||
@@ -104,14 +87,54 @@ export class SaleInvoicesService {
|
||||
items: {
|
||||
select: {
|
||||
id: true,
|
||||
notes: true,
|
||||
unit_price: true,
|
||||
discount: true,
|
||||
quantity: true,
|
||||
total_amount: true,
|
||||
payload: true,
|
||||
good: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
pricing_model: true,
|
||||
unit_type: true,
|
||||
|
||||
category: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
image_url: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
customer: {
|
||||
select: {
|
||||
id: true,
|
||||
type: true,
|
||||
customer_legal: {
|
||||
select: {
|
||||
company_name: true,
|
||||
economic_code: true,
|
||||
registration_number: true,
|
||||
postal_code: true,
|
||||
},
|
||||
},
|
||||
customer_individual: {
|
||||
select: {
|
||||
first_name: true,
|
||||
last_name: true,
|
||||
economic_code: true,
|
||||
national_id: true,
|
||||
postal_code: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
unknown_customer: true,
|
||||
},
|
||||
})
|
||||
return ResponseMapper.single(invoice)
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { PartnerInfo } from '@/common/decorators/partnerInfo.decorator'
|
||||
import { Body, Controller, Param, Post } from '@nestjs/common'
|
||||
import { ApiTags } from '@nestjs/swagger'
|
||||
import { PartnerBusinessActivityAccountsChargeService } from './accounts-charge.service'
|
||||
import { CreateBusinessActivityAccountsChargeDto } from './dto/accounts-charge.dto'
|
||||
|
||||
@ApiTags('PartnerConsumerBAAccountsCharge')
|
||||
@Controller(
|
||||
'partner/consumers/:consumerId/business-activities/:businessActivityId/accounts-charge',
|
||||
)
|
||||
export class PartnerBusinessActivityAccountsChargeController {
|
||||
constructor(private readonly service: PartnerBusinessActivityAccountsChargeService) {}
|
||||
|
||||
@Post()
|
||||
async create(
|
||||
@PartnerInfo('id') partnerId: string,
|
||||
@Param('consumerId') consumerId: string,
|
||||
@Param('businessActivityId') businessActivityId: string,
|
||||
@Body() data: CreateBusinessActivityAccountsChargeDto,
|
||||
) {
|
||||
return this.service.create(partnerId, consumerId, businessActivityId, data)
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import { PrismaModule } from '@/prisma/prisma.module'
|
||||
import { Module } from '@nestjs/common'
|
||||
import { PartnerBusinessActivityAccountsChargeController } from './accounts-charge.controller'
|
||||
import { PartnerBusinessActivityAccountsChargeService } from './accounts-charge.service'
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule],
|
||||
controllers: [PartnerBusinessActivityAccountsChargeController],
|
||||
providers: [PartnerBusinessActivityAccountsChargeService],
|
||||
})
|
||||
export class PartnerBusinessActivityAccountsChargeModule {}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { BadRequestException, Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { CreateBusinessActivityAccountsChargeDto } from './dto/accounts-charge.dto'
|
||||
|
||||
@Injectable()
|
||||
export class PartnerBusinessActivityAccountsChargeService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async create(
|
||||
partner_id: string,
|
||||
consumer_id: string,
|
||||
business_activity_id: string,
|
||||
data: CreateBusinessActivityAccountsChargeDto,
|
||||
) {
|
||||
const { quantity } = data
|
||||
|
||||
const startOfDay = new Date()
|
||||
startOfDay.setHours(0, 0, 0, 0)
|
||||
|
||||
const result = await this.prisma.$transaction(async tx => {
|
||||
const activation = await tx.licenseActivation.findFirst({
|
||||
where: {
|
||||
business_activity_id,
|
||||
business_activity: {
|
||||
id: business_activity_id,
|
||||
consumer: {
|
||||
id: consumer_id,
|
||||
partner_id,
|
||||
},
|
||||
},
|
||||
OR: [
|
||||
{
|
||||
expires_at: {
|
||||
gte: startOfDay,
|
||||
},
|
||||
},
|
||||
{
|
||||
license_renews: {
|
||||
some: {
|
||||
expires_at: {
|
||||
gte: startOfDay,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (!activation) {
|
||||
throw new BadRequestException('لایسنس فعال برای این فعالیت تجاری یافت نشد.')
|
||||
}
|
||||
|
||||
const credits = await tx.partnerAccountQuotaCredit.findMany({
|
||||
where: {
|
||||
allocation: null,
|
||||
charge_transaction: {
|
||||
partner_id,
|
||||
activation_expires_at: {
|
||||
gte: startOfDay,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: [
|
||||
{
|
||||
charge_transaction: {
|
||||
activation_expires_at: 'asc',
|
||||
},
|
||||
},
|
||||
{
|
||||
created_at: 'asc',
|
||||
},
|
||||
],
|
||||
take: quantity,
|
||||
select: {
|
||||
id: true,
|
||||
charge_transaction: {
|
||||
select: {
|
||||
activation_expires_at: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (credits.length < quantity) {
|
||||
throw new BadRequestException('اعتبار کافی برای تخصیص حساب وجود ندارد.')
|
||||
}
|
||||
|
||||
const allocations = await Promise.all(
|
||||
credits.map(credit =>
|
||||
tx.licenseAccountAllocation.create({
|
||||
data: {
|
||||
license_activation: {
|
||||
connect: {
|
||||
id: activation.id,
|
||||
},
|
||||
},
|
||||
credit: {
|
||||
connect: {
|
||||
id: credit.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
credit_id: true,
|
||||
license_activation_id: true,
|
||||
created_at: true,
|
||||
},
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
return {
|
||||
quantity,
|
||||
activation_id: activation.id,
|
||||
allocations,
|
||||
}
|
||||
})
|
||||
|
||||
return ResponseMapper.create(result.allocations)
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { ApiProperty } from '@nestjs/swagger'
|
||||
import { IsInt, Min } from 'class-validator'
|
||||
|
||||
export class CreateBusinessActivityAccountsChargeDto {
|
||||
@ApiProperty({ minimum: 1, example: 1 })
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
quantity: number
|
||||
}
|
||||
@@ -1,11 +1,16 @@
|
||||
import { PrismaModule } from '@/prisma/prisma.module'
|
||||
import { Module } from '@nestjs/common'
|
||||
import { PartnerBusinessActivityAccountsChargeModule } from './accounts-charge/accounts-charge.module'
|
||||
import { BusinessActivitiesController } from './business-activities.controller'
|
||||
import { BusinessActivitiesService } from './business-activities.service'
|
||||
import { AdminBusinessActivityComplexesModule } from './complexes/complexes.module'
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule, AdminBusinessActivityComplexesModule],
|
||||
imports: [
|
||||
PrismaModule,
|
||||
AdminBusinessActivityComplexesModule,
|
||||
PartnerBusinessActivityAccountsChargeModule,
|
||||
],
|
||||
controllers: [BusinessActivitiesController],
|
||||
providers: [BusinessActivitiesService],
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ComplexSelect, ComplexWhereInput } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { BadRequestException, Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { CreateComplexDto, UpdateComplexDto } from './dto/complex.dto'
|
||||
|
||||
@@ -55,16 +55,62 @@ export class BusinessActivityComplexesService {
|
||||
}
|
||||
|
||||
async create(partner_id: string, business_id: string, data: CreateComplexDto) {
|
||||
const complex = await this.prisma.complex.create({
|
||||
data: {
|
||||
...data,
|
||||
business_activity: {
|
||||
connect: {
|
||||
id: business_id,
|
||||
const complex = this.prisma.$transaction(async tx => {
|
||||
const now = new Date()
|
||||
|
||||
const relatedLicense = await tx.licenseAccountAllocation.findFirst({
|
||||
where: {
|
||||
license_activation: {
|
||||
license: {
|
||||
charge_transaction: {
|
||||
partner_id,
|
||||
},
|
||||
},
|
||||
business_activity: {
|
||||
id: business_id,
|
||||
},
|
||||
OR: [
|
||||
{
|
||||
expires_at: {
|
||||
gte: now,
|
||||
},
|
||||
},
|
||||
{
|
||||
license_renews: {
|
||||
some: {
|
||||
expires_at: {
|
||||
gte: now,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
account_id: null,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (!relatedLicense) {
|
||||
throw new BadRequestException(
|
||||
`متاسفانه به دلیل به پایان رسیدن محدودیت تعریف کاربران برای این فعالیت اقتصادی،امکان ایجاد شعبهی جدید وجود ندارد.`,
|
||||
)
|
||||
}
|
||||
|
||||
return await this.prisma.complex.create({
|
||||
data: {
|
||||
...data,
|
||||
business_activity: {
|
||||
connect: {
|
||||
id: business_id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
return ResponseMapper.create(complex)
|
||||
}
|
||||
|
||||
|
||||
+40
-50
@@ -5,7 +5,7 @@ import {
|
||||
ConsumerRole,
|
||||
POSStatus,
|
||||
} from '@/generated/prisma/enums'
|
||||
import { PosCreateInput, PosSelect } from '@/generated/prisma/models'
|
||||
import { PosSelect } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { BadRequestException, Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
@@ -95,35 +95,6 @@ export class ComplexPosesService {
|
||||
}
|
||||
}
|
||||
|
||||
private readonly defaultInsert = (data: CreatePosDto, complex_id: string) => {
|
||||
const { device_id, provider_id, ...rest } = data
|
||||
|
||||
const dataToCreate: PosCreateInput = {
|
||||
...rest,
|
||||
complex: {
|
||||
connect: {
|
||||
id: complex_id,
|
||||
},
|
||||
},
|
||||
provider: provider_id
|
||||
? {
|
||||
connect: {
|
||||
id: provider_id,
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
device: device_id
|
||||
? {
|
||||
connect: {
|
||||
id: device_id,
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
}
|
||||
|
||||
return dataToCreate
|
||||
}
|
||||
|
||||
async findAll(partner_id: string, business_activity_id: string, complex_id: string) {
|
||||
const poses = await this.prisma.pos.findMany({
|
||||
where: this.defaultWhere(partner_id, complex_id, business_activity_id),
|
||||
@@ -155,26 +126,43 @@ export class ComplexPosesService {
|
||||
data: CreatePosDto,
|
||||
) {
|
||||
const pos = this.prisma.$transaction(async tx => {
|
||||
const ba = await tx.businessActivity.findUniqueOrThrow({
|
||||
const now = new Date()
|
||||
|
||||
const activeAccountAllocation = await tx.licenseAccountAllocation.findFirst({
|
||||
where: {
|
||||
id: business_activity_id,
|
||||
consumer: {
|
||||
partner_id,
|
||||
account_id: null,
|
||||
license_activation: {
|
||||
business_activity_id,
|
||||
OR: [
|
||||
{
|
||||
expires_at: {
|
||||
gte: now,
|
||||
},
|
||||
},
|
||||
{
|
||||
license_renews: {
|
||||
some: {
|
||||
expires_at: {
|
||||
gte: now,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
license: {
|
||||
charge_transaction: {
|
||||
partner_id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
select: {
|
||||
consumer_id: true,
|
||||
id: true,
|
||||
license_activation: {
|
||||
select: {
|
||||
_count: {
|
||||
business_activity: {
|
||||
select: {
|
||||
account_allocations: {
|
||||
where: {
|
||||
account_id: {
|
||||
not: undefined,
|
||||
},
|
||||
},
|
||||
},
|
||||
consumer_id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -182,7 +170,7 @@ export class ComplexPosesService {
|
||||
},
|
||||
})
|
||||
|
||||
if (!ba.license_activation?._count.account_allocations) {
|
||||
if (!activeAccountAllocation) {
|
||||
throw new BadRequestException(
|
||||
`محدودیت تعریف تعداد کاربران این فعالیت تجاری به پایان رسیده است.`,
|
||||
)
|
||||
@@ -198,9 +186,16 @@ export class ComplexPosesService {
|
||||
account: {
|
||||
create: {
|
||||
role: ConsumerRole.OPERATOR,
|
||||
|
||||
consumer: {
|
||||
connect: {
|
||||
id: ba.consumer_id,
|
||||
id: activeAccountAllocation.license_activation!.business_activity
|
||||
.consumer_id,
|
||||
},
|
||||
},
|
||||
account_allocation: {
|
||||
connect: {
|
||||
id: activeAccountAllocation.id,
|
||||
},
|
||||
},
|
||||
account: {
|
||||
@@ -274,9 +269,4 @@ export class ComplexPosesService {
|
||||
})
|
||||
return ResponseMapper.update(pos)
|
||||
}
|
||||
|
||||
// async delete(id: string) {
|
||||
// await this.prisma.complex.delete({ where: { id } })
|
||||
// return ResponseMapper.delete()
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { PartnerInfo } from '@/common/decorators/partnerInfo.decorator'
|
||||
import type { IPartnerPayload } from '@/common/models/partnerPayload.model'
|
||||
import { Controller, Get, Patch } from '@nestjs/common'
|
||||
import { ApiTags } from '@nestjs/swagger'
|
||||
import { UpdatePartnerProfileDto } from './dto/partner.dto'
|
||||
@@ -10,8 +11,8 @@ export class PartnerController {
|
||||
constructor(private service: PartnerService) {}
|
||||
|
||||
@Get('')
|
||||
async me(@PartnerInfo('id') partnerId: string) {
|
||||
return this.service.me(partnerId)
|
||||
async me(@PartnerInfo() { id, account_id }: IPartnerPayload) {
|
||||
return this.service.me(id, account_id)
|
||||
}
|
||||
|
||||
@Get('info')
|
||||
|
||||
@@ -10,9 +10,10 @@ export class PartnerService {
|
||||
|
||||
private readonly defaultSelect: PartnerAccountSelect = {}
|
||||
|
||||
async me(partner_id: string) {
|
||||
async me(partner_id: string, account_id: string) {
|
||||
const partner = await this.prisma.partnerAccount.findUniqueOrThrow({
|
||||
where: {
|
||||
id: account_id,
|
||||
partner_id,
|
||||
},
|
||||
select: {
|
||||
|
||||
@@ -19,16 +19,20 @@ export type PartnerBusinessActivityAllocationLimits = {
|
||||
remaining_credits: number
|
||||
}
|
||||
|
||||
export const getPartnerBusinessActivityAllocationLimits = async (
|
||||
const getPartnerBusinessActivityActiveActivation = async (
|
||||
prisma: PartnerBusinessActivityAllocationClient,
|
||||
params: GetPartnerBusinessActivityAllocationLimitsParams,
|
||||
): Promise<PartnerBusinessActivityAllocationLimits> => {
|
||||
options?: {
|
||||
includeAccountAllocations?: boolean
|
||||
},
|
||||
) => {
|
||||
const { partner_id, business_activity_id, referenceDate = new Date() } = params
|
||||
const { includeAccountAllocations = true } = options ?? {}
|
||||
|
||||
const startOfDay = new Date(referenceDate)
|
||||
startOfDay.setHours(0, 0, 0, 0)
|
||||
|
||||
const activation = await prisma.licenseActivation.findFirst({
|
||||
return prisma.licenseActivation.findFirst({
|
||||
where: {
|
||||
business_activity_id,
|
||||
business_activity: {
|
||||
@@ -53,16 +57,59 @@ export const getPartnerBusinessActivityAllocationLimits = async (
|
||||
},
|
||||
],
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
account_allocations: {
|
||||
select: {
|
||||
select: includeAccountAllocations
|
||||
? {
|
||||
id: true,
|
||||
account_allocations: {
|
||||
select: {
|
||||
id: true,
|
||||
account_id: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
: {
|
||||
id: true,
|
||||
account_id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export const hasPartnerBusinessActivityEmptyAccountAllocation = async (
|
||||
prisma: PartnerBusinessActivityAllocationClient,
|
||||
params: GetPartnerBusinessActivityAllocationLimitsParams,
|
||||
) => {
|
||||
const activation = await getPartnerBusinessActivityActiveActivation(prisma, params)
|
||||
|
||||
if (!activation) {
|
||||
throw new BadRequestException('لایسنس فعال برای این فعالیت تجاری یافت نشد.')
|
||||
}
|
||||
|
||||
return activation.account_allocations.some(
|
||||
account_allocation => !account_allocation.account_id,
|
||||
)
|
||||
}
|
||||
|
||||
export const getPartnerBusinessActivityEmptyAccountAllocation = async (
|
||||
prisma: PartnerBusinessActivityAllocationClient,
|
||||
params: GetPartnerBusinessActivityAllocationLimitsParams,
|
||||
) => {
|
||||
const activation = await getPartnerBusinessActivityActiveActivation(prisma, params)
|
||||
|
||||
if (!activation) {
|
||||
throw new BadRequestException('لایسنس فعال برای این فعالیت تجاری یافت نشد.')
|
||||
}
|
||||
|
||||
return (
|
||||
activation.account_allocations.find(
|
||||
account_allocation => !account_allocation.account_id,
|
||||
) ?? null
|
||||
)
|
||||
}
|
||||
|
||||
export const getPartnerBusinessActivityAllocationLimits = async (
|
||||
prisma: PartnerBusinessActivityAllocationClient,
|
||||
params: GetPartnerBusinessActivityAllocationLimitsParams,
|
||||
): Promise<PartnerBusinessActivityAllocationLimits> => {
|
||||
const activation = await getPartnerBusinessActivityActiveActivation(prisma, params)
|
||||
|
||||
if (!activation) {
|
||||
throw new BadRequestException('لایسنس فعال برای این فعالیت تجاری یافت نشد.')
|
||||
|
||||
+114
-109
@@ -1,5 +1,6 @@
|
||||
import { checkAndDecodeJwtToken } from '@/common/utils/jwt-user.util'
|
||||
import { ConsumerRole } from '@/generated/prisma/enums'
|
||||
import { POSStatus } from '@/generated/prisma/enums'
|
||||
import { PosSelect } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import {
|
||||
ForbiddenException,
|
||||
@@ -21,60 +22,11 @@ export class PosMiddleware implements NestMiddleware {
|
||||
const doForbidden = () => {
|
||||
throw new ForbiddenException('شما دسترسی لازم را ندارید')
|
||||
}
|
||||
try {
|
||||
const tokenAccount = checkAndDecodeJwtToken(req, this.jwtService)
|
||||
|
||||
const { type, role, account_id } = tokenAccount!
|
||||
|
||||
let posId = req.cookies['posId']
|
||||
|
||||
if (type !== 'CONSUMER') {
|
||||
return doForbidden()
|
||||
}
|
||||
|
||||
if (req.url.startsWith('/api/v1/pos/accessible')) {
|
||||
req.decodedToken = tokenAccount!
|
||||
return next()
|
||||
}
|
||||
|
||||
if (!posId || typeof posId !== 'string') {
|
||||
const pos = await this.prisma.pos.findMany({
|
||||
where: {
|
||||
complex: {
|
||||
business_activity: {
|
||||
consumer: {
|
||||
consumer_accounts: {
|
||||
some: {
|
||||
id: account_id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
permission_pos: {
|
||||
some: {
|
||||
permission: {
|
||||
consumer_account_id: account_id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (!pos?.length) {
|
||||
throw new ForbiddenException('پایانهی فروشی برای شما یافت نشد')
|
||||
}
|
||||
if (pos.length === 1) {
|
||||
posId = pos[0].id
|
||||
} else
|
||||
throw new PreconditionFailedException('پایانهی مورد نظر خود را انتخاب کنید.')
|
||||
}
|
||||
|
||||
const pos = await this.prisma.pos.findUnique({
|
||||
where: {
|
||||
id: posId,
|
||||
},
|
||||
select: {
|
||||
return this.prisma.$transaction(async tx => {
|
||||
try {
|
||||
const tokenAccount = checkAndDecodeJwtToken(req, this.jwtService)
|
||||
const { type, role, account_id } = tokenAccount!
|
||||
const posSelect: PosSelect = {
|
||||
id: true,
|
||||
complex: {
|
||||
select: {
|
||||
@@ -87,65 +39,118 @@ export class PosMiddleware implements NestMiddleware {
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if (!pos) {
|
||||
return doForbidden()
|
||||
}
|
||||
let posId = req.cookies['posId']
|
||||
|
||||
if (role !== ConsumerRole.OWNER) {
|
||||
const accountPermissions = await this.prisma.permissionConsumer.findUnique({
|
||||
where: {
|
||||
consumer_account_id: account_id,
|
||||
},
|
||||
select: {
|
||||
pos_permissions: {
|
||||
select: {
|
||||
pos_id: true,
|
||||
},
|
||||
},
|
||||
business_permissions: {
|
||||
select: {
|
||||
business_id: true,
|
||||
},
|
||||
},
|
||||
complex_permissions: {
|
||||
select: {
|
||||
complex_id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (
|
||||
!// accountPermissions?.business_permissions.some(
|
||||
// permission => permission.id,
|
||||
// ) ||
|
||||
// accountPermissions?.complex_permissions.some(
|
||||
// permission => permission.complex_id,
|
||||
// ) ||
|
||||
accountPermissions?.pos_permissions.some(permission => permission.pos_id)
|
||||
) {
|
||||
if (type !== 'CONSUMER') {
|
||||
return doForbidden()
|
||||
}
|
||||
}
|
||||
req.posData = {
|
||||
pos_id: posId,
|
||||
complex_id: pos.complex.id,
|
||||
business_id: pos.complex.id,
|
||||
guild_id: pos.complex.business_activity.guild_id,
|
||||
consumer_account_id: account_id,
|
||||
}
|
||||
req.decodedToken = tokenAccount!
|
||||
|
||||
return next()
|
||||
} catch (error) {
|
||||
if (error && typeof error === 'object') {
|
||||
throw error
|
||||
}
|
||||
if (req.url.startsWith('/api/v1/pos/accessible')) {
|
||||
req.decodedToken = tokenAccount!
|
||||
return next()
|
||||
}
|
||||
|
||||
return doForbidden()
|
||||
}
|
||||
let pos!: any
|
||||
|
||||
if (!posId || typeof posId !== 'string') {
|
||||
const poses = await tx.pos.findMany({
|
||||
where: {
|
||||
complex: {
|
||||
business_activity: {
|
||||
consumer: {
|
||||
consumer_accounts: {
|
||||
some: {
|
||||
id: account_id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
account_id,
|
||||
},
|
||||
select: posSelect,
|
||||
})
|
||||
|
||||
if (!poses?.length) {
|
||||
throw new ForbiddenException('پایانهی فروشی برای شما یافت نشد')
|
||||
}
|
||||
if (poses.length === 1) {
|
||||
pos = poses[0]
|
||||
posId = poses[0].id
|
||||
} else
|
||||
throw new PreconditionFailedException('پایانهی مورد نظر خود را انتخاب کنید.')
|
||||
}
|
||||
|
||||
if (!pos) {
|
||||
pos = await tx.pos.findUnique({
|
||||
where: {
|
||||
id: posId,
|
||||
status: POSStatus.ACTIVE,
|
||||
},
|
||||
select: posSelect,
|
||||
})
|
||||
}
|
||||
|
||||
if (!pos) {
|
||||
return doForbidden()
|
||||
}
|
||||
|
||||
// if (role !== ConsumerRole.OWNER) {
|
||||
// const accountPermissions = await tx.permissionConsumer.findUnique({
|
||||
// where: {
|
||||
// consumer_account_id: account_id,
|
||||
// },
|
||||
// select: {
|
||||
// pos_permissions: {
|
||||
// select: {
|
||||
// pos_id: true,
|
||||
// },
|
||||
// },
|
||||
// business_permissions: {
|
||||
// select: {
|
||||
// business_id: true,
|
||||
// },
|
||||
// },
|
||||
// complex_permissions: {
|
||||
// select: {
|
||||
// complex_id: true,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
// if (
|
||||
// !// accountPermissions?.business_permissions.some(
|
||||
// // permission => permission.id,
|
||||
// // ) ||
|
||||
// // accountPermissions?.complex_permissions.some(
|
||||
// // permission => permission.complex_id,
|
||||
// // ) ||
|
||||
// accountPermissions?.pos_permissions.some(permission => permission.pos_id)
|
||||
// ) {
|
||||
// return doForbidden()
|
||||
// }
|
||||
// }
|
||||
|
||||
req.posData = {
|
||||
pos_id: posId,
|
||||
complex_id: pos.complex.id,
|
||||
business_id: pos.complex.id,
|
||||
guild_id: pos.complex.business_activity.guild_id,
|
||||
consumer_account_id: account_id,
|
||||
}
|
||||
req.decodedToken = tokenAccount!
|
||||
|
||||
return next()
|
||||
} catch (error) {
|
||||
if (error && typeof error === 'object') {
|
||||
throw error
|
||||
}
|
||||
|
||||
return doForbidden()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user