feat: enhance business activities and sale invoices handling with new query constants and pagination support

This commit is contained in:
2026-05-16 14:49:23 +03:30
parent 83e7c26133
commit 5baf5bfea6
14 changed files with 154 additions and 41 deletions
@@ -71,7 +71,6 @@ export class BusinessActivitiesService {
consumer_id,
id,
this.defaultSelect,
true,
)
return ResponseMapper.single(this.prepareBusinessActivityResponse(businessActivity))
}
@@ -0,0 +1,18 @@
import { ApiPropertyOptional } from '@nestjs/swagger'
import { Type } from 'class-transformer'
import { IsOptional, Max, Min } from 'class-validator'
export class ConsumerSaleInvoicesFilterDto {
@ApiPropertyOptional({ type: Number, example: 1 })
@Type(() => Number)
@Min(1)
@IsOptional()
page?: number
@ApiPropertyOptional({ type: Number, example: 10, description: 'Max value is 50.' })
@Type(() => Number)
@Min(1)
@Max(50)
@IsOptional()
perPage?: number
}
@@ -1,8 +1,9 @@
import { PosInfo } from '@/common/decorators/posInfo.decorator'
import { TokenAccount } from '@/common/decorators/tokenInfo.decorator'
import type { IPosPayload } from '@/common/models'
import { Body, Controller, Get, Param, Post } from '@nestjs/common'
import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common'
import { ApiTags } from '@nestjs/swagger'
import { ConsumerSaleInvoicesFilterDto } from './dto/saleInvoices-filter.dto'
import type {
SaleInvoicesServiceFindAllResponseDto,
SaleInvoicesServiceFindOneResponseDto,
@@ -18,8 +19,15 @@ export class StatisticsController {
@Get('')
async findAll(
@TokenAccount('userId') consumerId: string,
@Query('page') page = '1',
@Query('perPage') perPage = '10',
): Promise<SaleInvoicesServiceFindAllResponseDto> {
return this.service.findAll(consumerId)
const filter: ConsumerSaleInvoicesFilterDto = {
page: Number(page) || 1,
perPage: Number(perPage) || 10,
}
return this.service.findAll(consumerId, filter)
}
@Get(':id')
@@ -12,6 +12,7 @@ import { PrismaService } from '@/prisma/prisma.service'
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper'
import { SalesInvoiceTspService } from '../../tspProviders/sales-invoice-tsp.service'
import { ConsumerSaleInvoicesFilterDto } from './dto/saleInvoices-filter.dto'
@Injectable()
export class SaleInvoicesService {
@@ -21,6 +22,9 @@ export class SaleInvoicesService {
private sharedSaleInvoiceActionsService: SharedSaleInvoiceActionsService,
) {}
private readonly defaultPerPage = 10
private readonly maxPerPage = 50
private readonly defaultSelect: SalesInvoiceSelect = {
pos: {
select: {
@@ -54,27 +58,45 @@ export class SaleInvoicesService {
}
}
async findAll(consumer_id: string, page = 1, perPage = 10) {
async findAll(consumer_id: string, filter: ConsumerSaleInvoicesFilterDto) {
const invoicesWhere: SalesInvoiceWhereInput = {
consumer_account: {
consumer_id,
},
}
const normalizedPageValue = Number(filter.page ?? 1)
const normalizedPage = Number.isFinite(normalizedPageValue)
? Math.max(1, Math.floor(normalizedPageValue))
: 1
const requestedPerPageValue = Number(filter.perPage ?? this.defaultPerPage)
const requestedPerPage = Number.isFinite(requestedPerPageValue)
? Math.max(1, Math.floor(requestedPerPageValue))
: this.defaultPerPage
const normalizedPerPage = Math.min(requestedPerPage, this.maxPerPage)
const [invoices, total] = await this.prisma.$transaction(async tx => [
await tx.salesInvoice.findMany({
where: invoicesWhere,
orderBy: {
created_at: 'desc',
},
skip: (normalizedPage - 1) * normalizedPerPage,
take: normalizedPerPage,
select: {
...QUERY_CONSTANTS.SALE_INVOICE.summarySelect,
...this.defaultSelect,
},
skip: (page - 1) * perPage,
take: perPage,
}),
await tx.salesInvoice.count({ where: invoicesWhere }),
])
const mappedInvoices = invoices.map(this.invoiceMapper)
return ResponseMapper.paginate(mappedInvoices, { page, perPage, total })
return ResponseMapper.paginate(mappedInvoices, {
page: normalizedPage,
perPage: normalizedPerPage,
total,
})
}
async findOne(consumer_id: string, id: string) {