feat: implement partner licenses module with pagination and filtering capabilities
This commit is contained in:
@@ -23,12 +23,22 @@ export class PosGuard {
|
|||||||
const { posId } = cookie
|
const { posId } = cookie
|
||||||
|
|
||||||
if (!posId) {
|
if (!posId) {
|
||||||
throw new ForbiddenException('شما دسترسی لازم را ندارید.')
|
return false
|
||||||
|
// throw new ForbiddenException('شما دسترسی لازم را ندارید.')
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkLicenseActivation = await this.prisma.licenseAccountAllocation.findFirst({
|
const checkLicenseActivation = await this.prisma.licenseAccountAllocation.findFirst({
|
||||||
where: {
|
where: {
|
||||||
account_id: tokenPayload.account_id,
|
OR: [
|
||||||
|
{
|
||||||
|
account_id: tokenPayload.account_id,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
account: {
|
||||||
|
consumer_id: tokenPayload.user?.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
license_activation: {
|
license_activation: {
|
||||||
OR: [
|
OR: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -84,6 +84,9 @@ export class ResponseMappingInterceptor implements NestInterceptor {
|
|||||||
// }
|
// }
|
||||||
break
|
break
|
||||||
case 'paginate': {
|
case 'paginate': {
|
||||||
|
const { items: a, ...rest } = wrapped
|
||||||
|
console.log(rest)
|
||||||
|
|
||||||
const items = Array.isArray(wrapped.items) ? wrapped.items : []
|
const items = Array.isArray(wrapped.items) ? wrapped.items : []
|
||||||
const total =
|
const total =
|
||||||
typeof wrapped.total === 'number' ? wrapped.total : items.length
|
typeof wrapped.total === 'number' ? wrapped.total : items.length
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ export type MapperWrapper<T> =
|
|||||||
| { __mapped: 'delete' }
|
| { __mapped: 'delete' }
|
||||||
|
|
||||||
interface IPaginateMeta {
|
interface IPaginateMeta {
|
||||||
count: number
|
total: number
|
||||||
page?: number
|
page?: number
|
||||||
pageSize?: number
|
perPage?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ResponseMapper = {
|
export const ResponseMapper = {
|
||||||
@@ -38,12 +38,12 @@ export const ResponseMapper = {
|
|||||||
return { __mapped: 'list', items }
|
return { __mapped: 'list', items }
|
||||||
},
|
},
|
||||||
|
|
||||||
paginate<T>(items: T[], { count, page = 1, pageSize: perPage }: IPaginateMeta) {
|
paginate<T>(items: T[], { total, page = 1, perPage }: IPaginateMeta) {
|
||||||
return { __mapped: 'paginate', items, count, page, perPage }
|
return { __mapped: 'paginate', items, total, page, perPage }
|
||||||
},
|
},
|
||||||
|
|
||||||
sequelizePaginate<T>(rows: T[], count: number, page = 1, pageSize = rows.length) {
|
sequelizePaginate<T>(rows: T[], total: number, page = 1, pageSize = rows.length) {
|
||||||
return { __mapped: 'sequelize', rows, count, page, pageSize }
|
return { __mapped: 'sequelize', rows, total, page, pageSize }
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,14 +46,14 @@ export class AdminConsumersService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findAll() {
|
async findAll() {
|
||||||
const [consumers, count] = await this.prisma.$transaction([
|
const [consumers, total] = await this.prisma.$transaction([
|
||||||
this.prisma.consumer.findMany({
|
this.prisma.consumer.findMany({
|
||||||
select: this.defaultSelect,
|
select: this.defaultSelect,
|
||||||
}),
|
}),
|
||||||
this.prisma.consumer.count(),
|
this.prisma.consumer.count(),
|
||||||
])
|
])
|
||||||
|
|
||||||
return ResponseMapper.paginate(consumers.map(mapConsumerWithLicenseUtil), { count })
|
return ResponseMapper.paginate(consumers.map(mapConsumerWithLicenseUtil), { total })
|
||||||
}
|
}
|
||||||
|
|
||||||
async findOne(id: string) {
|
async findOne(id: string) {
|
||||||
|
|||||||
@@ -7,16 +7,16 @@ import { CreateDeviceDto, UpdateDeviceDto } from './dto/device.dto'
|
|||||||
export class DevicesService {
|
export class DevicesService {
|
||||||
constructor(private readonly prisma: PrismaService) {}
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
async findAll(page = 1, pageSize = 10) {
|
async findAll(page = 1, perPage = 10) {
|
||||||
const [items, count] = await this.prisma.$transaction([
|
const [items, total] = await this.prisma.$transaction([
|
||||||
this.prisma.device.findMany({
|
this.prisma.device.findMany({
|
||||||
skip: (page - 1) * pageSize,
|
skip: (page - 1) * perPage,
|
||||||
take: pageSize,
|
take: perPage,
|
||||||
include: { brand: true },
|
include: { brand: true },
|
||||||
}),
|
}),
|
||||||
this.prisma.device.count(),
|
this.prisma.device.count(),
|
||||||
])
|
])
|
||||||
return ResponseMapper.paginate(items, { count, page, pageSize })
|
return ResponseMapper.paginate(items, { total, page, perPage })
|
||||||
}
|
}
|
||||||
|
|
||||||
async findOne(id: string) {
|
async findOne(id: string) {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export class GoodsService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
async findAll(guildId: string) {
|
async findAll(guildId: string) {
|
||||||
const [goods, count] = await this.prisma.$transaction([
|
const [goods, total] = await this.prisma.$transaction([
|
||||||
this.prisma.good.findMany({
|
this.prisma.good.findMany({
|
||||||
where: this.defaultWhere(guildId),
|
where: this.defaultWhere(guildId),
|
||||||
select: this.defaultSelect,
|
select: this.defaultSelect,
|
||||||
@@ -45,7 +45,7 @@ export class GoodsService {
|
|||||||
this.prisma.good.count(),
|
this.prisma.good.count(),
|
||||||
])
|
])
|
||||||
return ResponseMapper.paginate(goods, {
|
return ResponseMapper.paginate(goods, {
|
||||||
count,
|
total,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export class GuildsService {
|
|||||||
constructor(private prisma: PrismaService) {}
|
constructor(private prisma: PrismaService) {}
|
||||||
|
|
||||||
async findAll() {
|
async findAll() {
|
||||||
const [guilds, count] = await this.prisma.$transaction([
|
const [guilds, total] = await this.prisma.$transaction([
|
||||||
this.prisma.guild.findMany({
|
this.prisma.guild.findMany({
|
||||||
include: {
|
include: {
|
||||||
_count: {
|
_count: {
|
||||||
@@ -30,7 +30,7 @@ export class GuildsService {
|
|||||||
businessActivitiesCount: guild._count.business_activities,
|
businessActivitiesCount: guild._count.business_activities,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
{ count },
|
{ total },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,20 +48,20 @@ export class PartnerLicensesService {
|
|||||||
created_at: true,
|
created_at: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAll(page = 1, pageSize = 10) {
|
async findAll(page = 1, perPage = 10) {
|
||||||
const [licenses, count] = await this.prisma.$transaction([
|
const [licenses, total] = await this.prisma.$transaction([
|
||||||
this.prisma.licenseActivation.findMany({
|
this.prisma.licenseActivation.findMany({
|
||||||
select: this.licenseDefaultSelect,
|
select: this.licenseDefaultSelect,
|
||||||
skip: (page - 1) * pageSize,
|
skip: (page - 1) * perPage,
|
||||||
take: pageSize,
|
take: perPage,
|
||||||
}),
|
}),
|
||||||
this.prisma.licenseActivation.count(),
|
this.prisma.licenseActivation.count(),
|
||||||
])
|
])
|
||||||
|
|
||||||
return ResponseMapper.paginate(licenses, {
|
return ResponseMapper.paginate(licenses, {
|
||||||
count,
|
total,
|
||||||
page,
|
page,
|
||||||
pageSize,
|
perPage,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { ResponseMapper } from 'common/response/response-mapper'
|
|||||||
export class PartnerActivatedLicensesService {
|
export class PartnerActivatedLicensesService {
|
||||||
constructor(private readonly prisma: PrismaService) {}
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
async findAll(partner_id: string, page = 1, pageSize = 10) {
|
async findAll(partner_id: string, page = 1, perPage = 10) {
|
||||||
const defaultWhere: LicenseActivationWhereInput = {
|
const defaultWhere: LicenseActivationWhereInput = {
|
||||||
license: {
|
license: {
|
||||||
charge_transaction: {
|
charge_transaction: {
|
||||||
@@ -15,11 +15,11 @@ export class PartnerActivatedLicensesService {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
const [licenses, count] = await this.prisma.$transaction(async tx => [
|
const [licenses, total] = await this.prisma.$transaction(async tx => [
|
||||||
await tx.licenseActivation.findMany({
|
await tx.licenseActivation.findMany({
|
||||||
where: defaultWhere,
|
where: defaultWhere,
|
||||||
skip: (page - 1) * pageSize,
|
skip: (page - 1) * perPage,
|
||||||
take: pageSize,
|
take: perPage,
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
starts_at: true,
|
starts_at: true,
|
||||||
@@ -71,8 +71,8 @@ export class PartnerActivatedLicensesService {
|
|||||||
|
|
||||||
return ResponseMapper.paginate(mappedLicenses, {
|
return ResponseMapper.paginate(mappedLicenses, {
|
||||||
page,
|
page,
|
||||||
pageSize,
|
perPage,
|
||||||
count,
|
total,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,18 +7,18 @@ import { ResponseMapper } from 'common/response/response-mapper'
|
|||||||
export class PartnerAllocatedAccountsService {
|
export class PartnerAllocatedAccountsService {
|
||||||
constructor(private readonly prisma: PrismaService) {}
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
async findAll(partner_id: string, page = 1, pageSize = 10) {
|
async findAll(partner_id: string, page = 1, perPage = 10) {
|
||||||
const defaultWhere: PartnerAccountQuotaCreditWhereInput = {
|
const defaultWhere: PartnerAccountQuotaCreditWhereInput = {
|
||||||
charge_transaction: {
|
charge_transaction: {
|
||||||
partner_id,
|
partner_id,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const [allocations, count] = await this.prisma.$transaction(async tx => [
|
const [allocations, total] = await this.prisma.$transaction(async tx => [
|
||||||
await tx.partnerAccountQuotaCredit.findMany({
|
await tx.partnerAccountQuotaCredit.findMany({
|
||||||
where: defaultWhere,
|
where: defaultWhere,
|
||||||
skip: (page - 1) * pageSize,
|
skip: (page - 1) * perPage,
|
||||||
take: pageSize,
|
take: perPage,
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
created_at: true,
|
created_at: true,
|
||||||
@@ -54,8 +54,8 @@ export class PartnerAllocatedAccountsService {
|
|||||||
|
|
||||||
return ResponseMapper.paginate(allocations, {
|
return ResponseMapper.paginate(allocations, {
|
||||||
page,
|
page,
|
||||||
pageSize,
|
perPage,
|
||||||
count,
|
total,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -51,16 +51,16 @@ export class PartnerAccountChargeTransactionService {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAll(partner_id: string, page = 1, pageSize = 10) {
|
async findAll(partner_id: string, page = 1, perPage = 10) {
|
||||||
const defaultWhere: PartnerAccountQuotaChargeTransactionWhereInput = {
|
const defaultWhere: PartnerAccountQuotaChargeTransactionWhereInput = {
|
||||||
partner_id,
|
partner_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
const [transactions, count] = await this.prisma.$transaction(async tx => [
|
const [transactions, total] = await this.prisma.$transaction(async tx => [
|
||||||
await tx.partnerAccountQuotaChargeTransaction.findMany({
|
await tx.partnerAccountQuotaChargeTransaction.findMany({
|
||||||
where: defaultWhere,
|
where: defaultWhere,
|
||||||
skip: (page - 1) * pageSize,
|
skip: (page - 1) * perPage,
|
||||||
take: pageSize,
|
take: perPage,
|
||||||
select: this.defaultSelect,
|
select: this.defaultSelect,
|
||||||
}),
|
}),
|
||||||
await tx.partnerAccountQuotaChargeTransaction.count({
|
await tx.partnerAccountQuotaChargeTransaction.count({
|
||||||
@@ -72,8 +72,8 @@ export class PartnerAccountChargeTransactionService {
|
|||||||
|
|
||||||
return ResponseMapper.paginate(mappedTransactions, {
|
return ResponseMapper.paginate(mappedTransactions, {
|
||||||
page,
|
page,
|
||||||
pageSize,
|
perPage,
|
||||||
count,
|
total,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -51,16 +51,16 @@ export class PartnerLicenseChargeTransactionService {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAll(partner_id: string, page = 1, pageSize = 10) {
|
async findAll(partner_id: string, page = 1, perPage = 10) {
|
||||||
const defaultWhere: LicenseChargeTransactionWhereInput = {
|
const defaultWhere: LicenseChargeTransactionWhereInput = {
|
||||||
partner_id,
|
partner_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
const [transactions, count] = await this.prisma.$transaction(async tx => [
|
const [transactions, total] = await this.prisma.$transaction(async tx => [
|
||||||
await tx.licenseChargeTransaction.findMany({
|
await tx.licenseChargeTransaction.findMany({
|
||||||
where: defaultWhere,
|
where: defaultWhere,
|
||||||
skip: (page - 1) * pageSize,
|
skip: (page - 1) * perPage,
|
||||||
take: pageSize,
|
take: perPage,
|
||||||
select: this.defaultSelect,
|
select: this.defaultSelect,
|
||||||
}),
|
}),
|
||||||
await tx.licenseChargeTransaction.count({
|
await tx.licenseChargeTransaction.count({
|
||||||
@@ -72,8 +72,8 @@ export class PartnerLicenseChargeTransactionService {
|
|||||||
|
|
||||||
return ResponseMapper.paginate(mappedTransactions, {
|
return ResponseMapper.paginate(mappedTransactions, {
|
||||||
page,
|
page,
|
||||||
pageSize,
|
perPage,
|
||||||
count,
|
total,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ export class AdminUsersService {
|
|||||||
constructor(private readonly prisma: PrismaService) {}
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
async findAll() {
|
async findAll() {
|
||||||
const [users, count] = await this.prisma.$transaction([
|
const [users, total] = await this.prisma.$transaction([
|
||||||
this.prisma.admin.findMany(),
|
this.prisma.admin.findMany(),
|
||||||
this.prisma.admin.count(),
|
this.prisma.admin.count(),
|
||||||
])
|
])
|
||||||
return ResponseMapper.paginate(
|
return ResponseMapper.paginate(
|
||||||
users.map(user => ({ ...user, fullname: `${user.first_name} ${user.last_name}` })),
|
users.map(user => ({ ...user, fullname: `${user.first_name} ${user.last_name}` })),
|
||||||
{ count },
|
{ total },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -20,10 +20,10 @@ export class SalesInvoicesService {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const pageSize = 10
|
const perPage = 10
|
||||||
const page = 1
|
const page = 1
|
||||||
|
|
||||||
const [items, count] = await this.prisma.$transaction([
|
const [items, total] = await this.prisma.$transaction([
|
||||||
this.prisma.salesInvoice.findMany({
|
this.prisma.salesInvoice.findMany({
|
||||||
where: defaultWhere,
|
where: defaultWhere,
|
||||||
select: {
|
select: {
|
||||||
@@ -91,14 +91,14 @@ export class SalesInvoicesService {
|
|||||||
},
|
},
|
||||||
unknown_customer: true,
|
unknown_customer: true,
|
||||||
},
|
},
|
||||||
skip: (page - 1) * pageSize,
|
skip: (page - 1) * perPage,
|
||||||
take: pageSize,
|
take: perPage,
|
||||||
}),
|
}),
|
||||||
this.prisma.salesInvoice.count({
|
this.prisma.salesInvoice.count({
|
||||||
where: defaultWhere,
|
where: defaultWhere,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
return ResponseMapper.paginate(items, { count, page, pageSize })
|
return ResponseMapper.paginate(items, { total, page, perPage })
|
||||||
}
|
}
|
||||||
|
|
||||||
findOne(complex_id: string, pos_id: string, id: string) {
|
findOne(complex_id: string, pos_id: string, id: string) {
|
||||||
|
|||||||
@@ -60,19 +60,19 @@ export class consumerCustomersService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAll(consumer_id: string, page = 1, pageSize = 10) {
|
async findAll(consumer_id: string, page = 1, perPage = 10) {
|
||||||
const [customers, count] = await this.prisma.$transaction(async tx => [
|
const [customers, total] = await this.prisma.$transaction(async tx => [
|
||||||
await tx.customer.findMany({
|
await tx.customer.findMany({
|
||||||
where: this.defaultWhere(consumer_id),
|
where: this.defaultWhere(consumer_id),
|
||||||
select: this.defaultSelect,
|
select: this.defaultSelect,
|
||||||
skip: (page - 1) * pageSize,
|
skip: (page - 1) * perPage,
|
||||||
take: 10,
|
take: 10,
|
||||||
}),
|
}),
|
||||||
await tx.customer.count({
|
await tx.customer.count({
|
||||||
where: this.defaultWhere(consumer_id),
|
where: this.defaultWhere(consumer_id),
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
return ResponseMapper.paginate(customers, { count, page, pageSize })
|
return ResponseMapper.paginate(customers, { total, page, perPage })
|
||||||
}
|
}
|
||||||
|
|
||||||
async findOne(consumer_id: string, customer_id: string) {
|
async findOne(consumer_id: string, customer_id: string) {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export class CustomerSaleInvoicesService {
|
|||||||
created_at: true,
|
created_at: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAll(consumer_id: string, customer_id: string, page = 1, pageSize = 10) {
|
async findAll(consumer_id: string, customer_id: string, page = 1, perPage = 10) {
|
||||||
const salesWhere: SalesInvoiceWhereInput = {
|
const salesWhere: SalesInvoiceWhereInput = {
|
||||||
customer_id,
|
customer_id,
|
||||||
pos: {
|
pos: {
|
||||||
@@ -62,7 +62,7 @@ export class CustomerSaleInvoicesService {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const [accounts, count] = await this.prisma.$transaction(async tx => [
|
const [accounts, total] = await this.prisma.$transaction(async tx => [
|
||||||
await tx.salesInvoice.findMany({
|
await tx.salesInvoice.findMany({
|
||||||
where: salesWhere,
|
where: salesWhere,
|
||||||
select: {
|
select: {
|
||||||
@@ -73,7 +73,7 @@ export class CustomerSaleInvoicesService {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
skip: (page - 1) * pageSize,
|
skip: (page - 1) * perPage,
|
||||||
take: 10,
|
take: 10,
|
||||||
}),
|
}),
|
||||||
await tx.salesInvoice.count({
|
await tx.salesInvoice.count({
|
||||||
@@ -90,9 +90,9 @@ export class CustomerSaleInvoicesService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return ResponseMapper.paginate(mappedAccounts, {
|
return ResponseMapper.paginate(mappedAccounts, {
|
||||||
count,
|
total,
|
||||||
page,
|
page,
|
||||||
pageSize,
|
perPage,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,22 +47,22 @@ export class SaleInvoicesService {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAll(consumer_id: string, page = 1, pageSize = 10) {
|
async findAll(consumer_id: string, page = 1, perPage = 10) {
|
||||||
const invoicesWhere: SalesInvoiceWhereInput = {
|
const invoicesWhere: SalesInvoiceWhereInput = {
|
||||||
consumer_account: {
|
consumer_account: {
|
||||||
consumer_id,
|
consumer_id,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
const [invoices, count] = await this.prisma.$transaction(async tx => [
|
const [invoices, total] = await this.prisma.$transaction(async tx => [
|
||||||
await tx.salesInvoice.findMany({
|
await tx.salesInvoice.findMany({
|
||||||
where: invoicesWhere,
|
where: invoicesWhere,
|
||||||
select: this.defaultSelect,
|
select: this.defaultSelect,
|
||||||
skip: (page - 1) * pageSize,
|
skip: (page - 1) * perPage,
|
||||||
take: pageSize,
|
take: perPage,
|
||||||
}),
|
}),
|
||||||
await tx.salesInvoice.count({ where: invoicesWhere }),
|
await tx.salesInvoice.count({ where: invoicesWhere }),
|
||||||
])
|
])
|
||||||
return ResponseMapper.paginate(invoices, { page, pageSize, count })
|
return ResponseMapper.paginate(invoices, { page, perPage, total })
|
||||||
}
|
}
|
||||||
|
|
||||||
async findOne(consumer_id: string, id: string) {
|
async findOne(consumer_id: string, id: string) {
|
||||||
|
|||||||
@@ -37,12 +37,12 @@ export class PartnerConsumersService {
|
|||||||
partner_id,
|
partner_id,
|
||||||
})
|
})
|
||||||
|
|
||||||
async findAll(partner_id: string, page = 1, pageSize = 10) {
|
async findAll(partner_id: string, page = 1, perPage = 10) {
|
||||||
const [consumers, count] = await this.prisma.$transaction(async tx => [
|
const [consumers, total] = await this.prisma.$transaction(async tx => [
|
||||||
await tx.consumer.findMany({
|
await tx.consumer.findMany({
|
||||||
where: this.defaultWhere(partner_id),
|
where: this.defaultWhere(partner_id),
|
||||||
select: this.defaultSelect,
|
select: this.defaultSelect,
|
||||||
skip: (page - 1) * pageSize,
|
skip: (page - 1) * perPage,
|
||||||
take: 10,
|
take: 10,
|
||||||
}),
|
}),
|
||||||
await tx.consumer.count({
|
await tx.consumer.count({
|
||||||
@@ -50,9 +50,9 @@ export class PartnerConsumersService {
|
|||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
return ResponseMapper.paginate(consumers.map(mapConsumerWithLicenseUtil), {
|
return ResponseMapper.paginate(consumers.map(mapConsumerWithLicenseUtil), {
|
||||||
count,
|
total,
|
||||||
page,
|
page,
|
||||||
pageSize,
|
perPage,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger'
|
||||||
|
import { Paginated } from 'common/response/response-mapper'
|
||||||
|
|
||||||
|
export interface PartnerLicenseActivationConsumerResponseDto {
|
||||||
|
id: string
|
||||||
|
first_name: string
|
||||||
|
last_name: string
|
||||||
|
mobile_number: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PartnerLicenseActivationBusinessActivityResponseDto {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
consumer: PartnerLicenseActivationConsumerResponseDto
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PartnerLicenseActivationChargeTransactionResponseDto {
|
||||||
|
id: string
|
||||||
|
tracking_code: string
|
||||||
|
activation_expires_at: Date
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PartnerLicenseActivationLicenseResponseDto {
|
||||||
|
id: string
|
||||||
|
accounts_limit: number
|
||||||
|
charge_transaction: PartnerLicenseActivationChargeTransactionResponseDto
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PartnerLicenseActivationCountResponseDto {
|
||||||
|
account_allocations: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PartnerLicenseActivationResponseDto {
|
||||||
|
id: string
|
||||||
|
starts_at: Date
|
||||||
|
expires_at: Date
|
||||||
|
created_at: Date
|
||||||
|
updated_at: Date
|
||||||
|
business_activity: PartnerLicenseActivationBusinessActivityResponseDto
|
||||||
|
license: PartnerLicenseActivationLicenseResponseDto
|
||||||
|
_count: PartnerLicenseActivationCountResponseDto
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PartnerLicenseActivationPaginatedResponseDto =
|
||||||
|
Paginated<PartnerLicenseActivationResponseDto>
|
||||||
|
|
||||||
|
export class PartnerLicenseActivationConsumerResponseSchema {
|
||||||
|
@ApiProperty()
|
||||||
|
id: string
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
first_name: string
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
last_name: string
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
mobile_number: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PartnerLicenseActivationBusinessActivityResponseSchema {
|
||||||
|
@ApiProperty()
|
||||||
|
id: string
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
name: string
|
||||||
|
|
||||||
|
@ApiProperty({ type: () => PartnerLicenseActivationConsumerResponseSchema })
|
||||||
|
consumer: PartnerLicenseActivationConsumerResponseSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PartnerLicenseActivationChargeTransactionResponseSchema {
|
||||||
|
@ApiProperty()
|
||||||
|
id: string
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
tracking_code: string
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
activation_expires_at: Date
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PartnerLicenseActivationLicenseResponseSchema {
|
||||||
|
@ApiProperty()
|
||||||
|
id: string
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
accounts_limit: number
|
||||||
|
|
||||||
|
@ApiProperty({ type: () => PartnerLicenseActivationChargeTransactionResponseSchema })
|
||||||
|
charge_transaction: PartnerLicenseActivationChargeTransactionResponseSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PartnerLicenseActivationCountResponseSchema {
|
||||||
|
@ApiProperty()
|
||||||
|
account_allocations: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PartnerLicenseActivationResponseSchema {
|
||||||
|
@ApiProperty()
|
||||||
|
id: string
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
starts_at: Date
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
expires_at: Date
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
created_at: Date
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
updated_at: Date
|
||||||
|
|
||||||
|
@ApiProperty({ type: () => PartnerLicenseActivationBusinessActivityResponseSchema })
|
||||||
|
business_activity: PartnerLicenseActivationBusinessActivityResponseSchema
|
||||||
|
|
||||||
|
@ApiProperty({ type: () => PartnerLicenseActivationLicenseResponseSchema })
|
||||||
|
license: PartnerLicenseActivationLicenseResponseSchema
|
||||||
|
|
||||||
|
@ApiProperty({ type: () => PartnerLicenseActivationCountResponseSchema })
|
||||||
|
_count: PartnerLicenseActivationCountResponseSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PartnerLicenseActivationPaginatedResponseSchema {
|
||||||
|
@ApiProperty({ example: 'paginate' })
|
||||||
|
__mapped: string
|
||||||
|
|
||||||
|
@ApiProperty({ type: () => [PartnerLicenseActivationResponseSchema] })
|
||||||
|
items: PartnerLicenseActivationResponseSchema[]
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
total: number
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
page: number
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
perPage: number
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { PartnerInfo } from '@/common/decorators/partnerInfo.decorator'
|
||||||
|
import { Controller, Get, Query } from '@nestjs/common'
|
||||||
|
import { ApiOkResponse, ApiQuery, ApiTags } from '@nestjs/swagger'
|
||||||
|
import { PartnerLicenseActivationPaginatedResponseSchema } from './dto/licenses-response.dto'
|
||||||
|
import { PartnerLicensesService } from './licenses.service'
|
||||||
|
|
||||||
|
@ApiTags('PartnerLicenses')
|
||||||
|
@Controller('partner/licenses')
|
||||||
|
export class PartnerLicensesController {
|
||||||
|
constructor(private readonly service: PartnerLicensesService) {}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@ApiQuery({ name: 'page', required: false, type: Number, example: 1 })
|
||||||
|
@ApiQuery({
|
||||||
|
name: 'perPage',
|
||||||
|
required: false,
|
||||||
|
type: Number,
|
||||||
|
example: 10,
|
||||||
|
description: 'Max value is 50.',
|
||||||
|
})
|
||||||
|
@ApiQuery({ name: 'consumer_name', required: false, type: String })
|
||||||
|
@ApiQuery({ name: 'consumer_mobile', required: false, type: String })
|
||||||
|
@ApiQuery({
|
||||||
|
name: 'expires_from',
|
||||||
|
required: false,
|
||||||
|
type: String,
|
||||||
|
example: '2026-01-01',
|
||||||
|
})
|
||||||
|
@ApiQuery({ name: 'expires_to', required: false, type: String, example: '2026-12-31' })
|
||||||
|
@ApiOkResponse({ type: PartnerLicenseActivationPaginatedResponseSchema })
|
||||||
|
async findAll(
|
||||||
|
@PartnerInfo('id') partnerId: string,
|
||||||
|
@Query('page') page = '1',
|
||||||
|
@Query('perPage') perPage = '10',
|
||||||
|
@Query('consumer_name') consumer_name?: string,
|
||||||
|
@Query('consumer_mobile') consumer_mobile?: string,
|
||||||
|
@Query('expires_from') expires_from?: string,
|
||||||
|
@Query('expires_to') expires_to?: string,
|
||||||
|
) {
|
||||||
|
return this.service.findAll(partnerId, {
|
||||||
|
page: Number(page) || 1,
|
||||||
|
perPage: Number(perPage) || 10,
|
||||||
|
consumer_name,
|
||||||
|
consumer_mobile,
|
||||||
|
expires_from,
|
||||||
|
expires_to,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { PrismaModule } from '@/prisma/prisma.module'
|
||||||
|
import { Module } from '@nestjs/common'
|
||||||
|
import { PartnerLicensesController } from './licenses.controller'
|
||||||
|
import { PartnerLicensesService } from './licenses.service'
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [PrismaModule],
|
||||||
|
controllers: [PartnerLicensesController],
|
||||||
|
providers: [PartnerLicensesService],
|
||||||
|
})
|
||||||
|
export class PartnerLicensesModule {}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
import { PrismaService } from '@/prisma/prisma.service'
|
||||||
|
import { BadRequestException, Injectable } from '@nestjs/common'
|
||||||
|
import { ResponseMapper } from 'common/response/response-mapper'
|
||||||
|
import {
|
||||||
|
PartnerLicenseActivationPaginatedResponseDto,
|
||||||
|
PartnerLicenseActivationResponseDto,
|
||||||
|
} from './dto/licenses-response.dto'
|
||||||
|
|
||||||
|
type FindPartnerLicensesParams = {
|
||||||
|
perPage?: number
|
||||||
|
page?: number
|
||||||
|
consumer_name?: string
|
||||||
|
consumer_mobile?: string
|
||||||
|
expires_from?: string
|
||||||
|
expires_to?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class PartnerLicensesService {
|
||||||
|
private readonly defaultPerPage = 10
|
||||||
|
private readonly maxPerPage = 50
|
||||||
|
|
||||||
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
|
async findAll(
|
||||||
|
partner_id: string,
|
||||||
|
params: FindPartnerLicensesParams = {},
|
||||||
|
): Promise<PartnerLicenseActivationPaginatedResponseDto> {
|
||||||
|
const { perPage, page, consumer_name, consumer_mobile, expires_from, expires_to } =
|
||||||
|
params
|
||||||
|
|
||||||
|
const normalizedPage = Number.isFinite(page)
|
||||||
|
? Math.max(1, Math.floor(page as number))
|
||||||
|
: 1
|
||||||
|
const requestedPerPage = Number.isFinite(perPage)
|
||||||
|
? Math.max(1, Math.floor(perPage as number))
|
||||||
|
: this.defaultPerPage
|
||||||
|
const normalizedPerPage = Math.min(requestedPerPage, this.maxPerPage)
|
||||||
|
|
||||||
|
const andWhere: any[] = [
|
||||||
|
{
|
||||||
|
license: {
|
||||||
|
charge_transaction: {
|
||||||
|
partner_id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const consumerName = consumer_name?.trim()
|
||||||
|
const consumerMobile = consumer_mobile?.trim()
|
||||||
|
|
||||||
|
if (consumerName || consumerMobile) {
|
||||||
|
andWhere.push({
|
||||||
|
business_activity: {
|
||||||
|
consumer: {
|
||||||
|
OR: [
|
||||||
|
{ first_name: { contains: consumerName } },
|
||||||
|
{ last_name: { contains: consumerName } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (consumerMobile) {
|
||||||
|
andWhere.push({
|
||||||
|
business_activity: {
|
||||||
|
consumer: {
|
||||||
|
mobile_number: {
|
||||||
|
contains: consumerMobile,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expires_from || expires_to) {
|
||||||
|
const expiresAtFilter: {
|
||||||
|
gte?: Date
|
||||||
|
lte?: Date
|
||||||
|
} = {}
|
||||||
|
|
||||||
|
if (expires_from) {
|
||||||
|
const fromDate = new Date(expires_from)
|
||||||
|
if (Number.isNaN(fromDate.getTime())) {
|
||||||
|
throw new BadRequestException('مقدار expires_from نامعتبر است.')
|
||||||
|
}
|
||||||
|
expiresAtFilter.gte = fromDate
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expires_to) {
|
||||||
|
const toDate = new Date(expires_to)
|
||||||
|
if (Number.isNaN(toDate.getTime())) {
|
||||||
|
throw new BadRequestException('مقدار expires_to نامعتبر است.')
|
||||||
|
}
|
||||||
|
expiresAtFilter.lte = toDate
|
||||||
|
}
|
||||||
|
|
||||||
|
andWhere.push({
|
||||||
|
expires_at: expiresAtFilter,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const where = { AND: andWhere }
|
||||||
|
|
||||||
|
const [licenseActivations, total] = await this.prisma.$transaction(async tx => [
|
||||||
|
await tx.licenseActivation.findMany({
|
||||||
|
where,
|
||||||
|
orderBy: {
|
||||||
|
created_at: 'desc',
|
||||||
|
},
|
||||||
|
skip: (normalizedPage - 1) * normalizedPerPage,
|
||||||
|
take: normalizedPerPage,
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
starts_at: true,
|
||||||
|
expires_at: true,
|
||||||
|
created_at: true,
|
||||||
|
updated_at: true,
|
||||||
|
business_activity: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
consumer: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
first_name: true,
|
||||||
|
last_name: true,
|
||||||
|
mobile_number: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
license: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
accounts_limit: true,
|
||||||
|
charge_transaction: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
tracking_code: true,
|
||||||
|
activation_expires_at: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
_count: {
|
||||||
|
select: {
|
||||||
|
account_allocations: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
await tx.licenseActivation.count({ where }),
|
||||||
|
])
|
||||||
|
|
||||||
|
return ResponseMapper.paginate<PartnerLicenseActivationResponseDto>(
|
||||||
|
licenseActivations,
|
||||||
|
{
|
||||||
|
total,
|
||||||
|
page: normalizedPage,
|
||||||
|
perPage: normalizedPerPage,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,13 +2,14 @@ import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/c
|
|||||||
import { JwtService } from '@nestjs/jwt'
|
import { JwtService } from '@nestjs/jwt'
|
||||||
import { PartnerAccountsModule } from './accounts/accounts.module'
|
import { PartnerAccountsModule } from './accounts/accounts.module'
|
||||||
import { PartnerCustomersModule } from './consumers/consumers.module'
|
import { PartnerCustomersModule } from './consumers/consumers.module'
|
||||||
|
import { PartnerLicensesModule } from './licenses/licenses.module'
|
||||||
import { PartnerController } from './partners.controller'
|
import { PartnerController } from './partners.controller'
|
||||||
import { PartnerMiddleware } from './partners.middleware'
|
import { PartnerMiddleware } from './partners.middleware'
|
||||||
import { PartnerService } from './partners.service'
|
import { PartnerService } from './partners.service'
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
controllers: [PartnerController],
|
controllers: [PartnerController],
|
||||||
imports: [PartnerAccountsModule, PartnerCustomersModule],
|
imports: [PartnerAccountsModule, PartnerCustomersModule, PartnerLicensesModule],
|
||||||
providers: [JwtService, PartnerService],
|
providers: [JwtService, PartnerService],
|
||||||
})
|
})
|
||||||
export class PartnerModule implements NestModule {
|
export class PartnerModule implements NestModule {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export class PosService {
|
|||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
name: true,
|
name: true,
|
||||||
|
branch_code: true,
|
||||||
business_activity: {
|
business_activity: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
@@ -72,6 +73,7 @@ export class PosService {
|
|||||||
complex: {
|
complex: {
|
||||||
id: complexId,
|
id: complexId,
|
||||||
name: complexName,
|
name: complexName,
|
||||||
|
branch_code: complex.branch_code,
|
||||||
},
|
},
|
||||||
businessActivity: {
|
businessActivity: {
|
||||||
id: businessId,
|
id: businessId,
|
||||||
|
|||||||
Reference in New Issue
Block a user