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:
2026-04-25 15:16:59 +03:30
parent 12506de863
commit b72e6c7194
36 changed files with 975 additions and 568 deletions
+114 -109
View File
@@ -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()
}
})
}
}