feat: enhance sale invoices filtering with additional fields and refactor findAll method

This commit is contained in:
2026-05-16 16:12:19 +03:30
parent 5baf5bfea6
commit ba3c544ff8
5 changed files with 228 additions and 16 deletions
@@ -1,6 +1,15 @@
import { ApiPropertyOptional } from '@nestjs/swagger'
import { Type } from 'class-transformer'
import { IsOptional, Max, Min } from 'class-validator'
import {
IsDateString,
IsEnum,
IsNumber,
IsOptional,
IsString,
Max,
Min,
} from 'class-validator'
import { TspProviderResponseStatus } from 'generated/prisma/enums'
export class ConsumerSaleInvoicesFilterDto {
@ApiPropertyOptional({ type: Number, example: 1 })
@@ -15,4 +24,72 @@ export class ConsumerSaleInvoicesFilterDto {
@Max(50)
@IsOptional()
perPage?: number
@ApiPropertyOptional()
@IsOptional()
@IsDateString()
invoice_date_from?: string
@ApiPropertyOptional()
@IsOptional()
@IsDateString()
invoice_date_to?: string
@ApiPropertyOptional()
@IsOptional()
@IsDateString()
created_at_from?: string
@ApiPropertyOptional()
@IsOptional()
@IsDateString()
created_at_to?: string
@ApiPropertyOptional()
@IsOptional()
@IsString()
code?: string
@ApiPropertyOptional()
@IsOptional()
@IsString()
customer_name?: string
@ApiPropertyOptional()
@IsOptional()
@IsString()
customer_mobile?: string
@ApiPropertyOptional()
@IsOptional()
@IsString()
customer_national_id?: string
@ApiPropertyOptional()
@IsOptional()
@IsString()
customer_economic_code?: string
@ApiPropertyOptional({ enum: TspProviderResponseStatus })
@IsOptional()
@IsEnum(TspProviderResponseStatus)
status?: TspProviderResponseStatus
@ApiPropertyOptional()
@IsOptional()
@Type(() => Number)
@IsNumber()
total_amount?: number
@ApiPropertyOptional()
@IsOptional()
@Type(() => Number)
@IsNumber()
total_amount_from?: number
@ApiPropertyOptional()
@IsOptional()
@Type(() => Number)
@IsNumber()
total_amount_to?: number
}
@@ -19,15 +19,9 @@ export class StatisticsController {
@Get('')
async findAll(
@TokenAccount('userId') consumerId: string,
@Query('page') page = '1',
@Query('perPage') perPage = '10',
@Query() query: ConsumerSaleInvoicesFilterDto,
): Promise<SaleInvoicesServiceFindAllResponseDto> {
const filter: ConsumerSaleInvoicesFilterDto = {
page: Number(page) || 1,
perPage: Number(perPage) || 10,
}
return this.service.findAll(consumerId, filter)
return this.service.findAll(consumerId, query)
}
@Get(':id')
@@ -59,11 +59,7 @@ export class SaleInvoicesService {
}
async findAll(consumer_id: string, filter: ConsumerSaleInvoicesFilterDto) {
const invoicesWhere: SalesInvoiceWhereInput = {
consumer_account: {
consumer_id,
},
}
const invoicesWhere = this.buildFindAllWhere(consumer_id, filter)
const normalizedPageValue = Number(filter.page ?? 1)
const normalizedPage = Number.isFinite(normalizedPageValue)
? Math.max(1, Math.floor(normalizedPageValue))
@@ -99,6 +95,146 @@ export class SaleInvoicesService {
})
}
private buildFindAllWhere(
consumer_id: string,
filter: ConsumerSaleInvoicesFilterDto,
): SalesInvoiceWhereInput {
const where: SalesInvoiceWhereInput = {
consumer_account: {
consumer_id,
},
}
if (filter.code?.trim()) {
where.code = {
contains: filter.code.trim(),
}
}
if (filter.invoice_date_from || filter.invoice_date_to) {
where.invoice_date = {
...(filter.invoice_date_from ? { gte: new Date(filter.invoice_date_from) } : {}),
...(filter.invoice_date_to ? { lte: new Date(filter.invoice_date_to) } : {}),
}
}
if (filter.created_at_from || filter.created_at_to) {
where.created_at = {
...(filter.created_at_from ? { gte: new Date(filter.created_at_from) } : {}),
...(filter.created_at_to ? { lte: new Date(filter.created_at_to) } : {}),
}
}
if (
filter.total_amount !== undefined ||
filter.total_amount_from !== undefined ||
filter.total_amount_to !== undefined
) {
where.total_amount = {
...(filter.total_amount !== undefined ? { equals: filter.total_amount } : {}),
...(filter.total_amount_from !== undefined
? { gte: filter.total_amount_from }
: {}),
...(filter.total_amount_to !== undefined ? { lte: filter.total_amount_to } : {}),
}
}
if (
filter.customer_name?.trim() ||
filter.customer_mobile?.trim() ||
filter.customer_national_id?.trim() ||
filter.customer_economic_code?.trim()
) {
where.customer = {
is: {
OR: [
...(filter.customer_name?.trim()
? [
{
individual: {
is: {
OR: [
{ first_name: { contains: filter.customer_name.trim() } },
{ last_name: { contains: filter.customer_name.trim() } },
],
},
},
},
{
legal: {
is: {
name: {
contains: filter.customer_name.trim(),
},
},
},
},
]
: []),
...(filter.customer_mobile?.trim()
? [
{
individual: {
is: {
mobile_number: { contains: filter.customer_mobile.trim() },
},
},
},
]
: []),
...(filter.customer_national_id?.trim()
? [
{
individual: {
is: {
national_id: { contains: filter.customer_national_id.trim() },
},
},
},
]
: []),
...(filter.customer_economic_code?.trim()
? [
{
legal: {
is: {
OR: [
{
economic_code: {
contains: filter.customer_economic_code.trim(),
},
},
{
registration_number: {
contains: filter.customer_economic_code.trim(),
},
},
],
},
},
},
]
: []),
],
},
}
}
if (filter.status) {
if (filter.status === TspProviderResponseStatus.NOT_SEND) {
where.tsp_attempts = undefined
} else {
where.tsp_attempts = {
some: {
status: filter.status,
},
}
}
}
return where
}
async findOne(consumer_id: string, id: string) {
const invoicesWhere: SalesInvoiceWhereUniqueInput = {
id,