feat: enhance sale invoices filtering with additional fields and refactor findAll method
This commit is contained in:
+5
-2
@@ -5,6 +5,7 @@ ARG NPM_REGISTRY=https://registry.npmjs.org/
|
|||||||
ENV NPM_CONFIG_REGISTRY=${NPM_REGISTRY}
|
ENV NPM_CONFIG_REGISTRY=${NPM_REGISTRY}
|
||||||
ENV npm_config_registry=${NPM_REGISTRY}
|
ENV npm_config_registry=${NPM_REGISTRY}
|
||||||
ENV PNPM_HOME="/pnpm"
|
ENV PNPM_HOME="/pnpm"
|
||||||
|
ENV PNPM_STORE_DIR="/pnpm/store"
|
||||||
ENV PATH="${PNPM_HOME}:${PATH}"
|
ENV PATH="${PNPM_HOME}:${PATH}"
|
||||||
ENV COREPACK_NPM_REGISTRY=${NPM_REGISTRY}
|
ENV COREPACK_NPM_REGISTRY=${NPM_REGISTRY}
|
||||||
ARG PNPM_VERSION=10.17.1
|
ARG PNPM_VERSION=10.17.1
|
||||||
@@ -15,7 +16,8 @@ RUN npm config set registry ${NPM_REGISTRY} \
|
|||||||
FROM base AS build
|
FROM base AS build
|
||||||
|
|
||||||
COPY package.json pnpm-lock.yaml ./
|
COPY package.json pnpm-lock.yaml ./
|
||||||
RUN pnpm install --frozen-lockfile
|
RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store \
|
||||||
|
pnpm install --frozen-lockfile
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
ENV PRISMA_CLIENT_ENGINE_TYPE=binary
|
ENV PRISMA_CLIENT_ENGINE_TYPE=binary
|
||||||
@@ -24,7 +26,8 @@ RUN pnpm run build
|
|||||||
FROM base AS prod-deps
|
FROM base AS prod-deps
|
||||||
|
|
||||||
COPY package.json pnpm-lock.yaml ./
|
COPY package.json pnpm-lock.yaml ./
|
||||||
RUN pnpm install --prod --frozen-lockfile \
|
RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store \
|
||||||
|
pnpm install --prod --frozen-lockfile \
|
||||||
&& pnpm store prune \
|
&& pnpm store prune \
|
||||||
&& rm -rf /root/.npm /root/.cache
|
&& rm -rf /root/.npm /root/.cache
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
import { ApiPropertyOptional } from '@nestjs/swagger'
|
import { ApiPropertyOptional } from '@nestjs/swagger'
|
||||||
import { Type } from 'class-transformer'
|
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 {
|
export class ConsumerSaleInvoicesFilterDto {
|
||||||
@ApiPropertyOptional({ type: Number, example: 1 })
|
@ApiPropertyOptional({ type: Number, example: 1 })
|
||||||
@@ -15,4 +24,72 @@ export class ConsumerSaleInvoicesFilterDto {
|
|||||||
@Max(50)
|
@Max(50)
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
perPage?: number
|
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('')
|
@Get('')
|
||||||
async findAll(
|
async findAll(
|
||||||
@TokenAccount('userId') consumerId: string,
|
@TokenAccount('userId') consumerId: string,
|
||||||
@Query('page') page = '1',
|
@Query() query: ConsumerSaleInvoicesFilterDto,
|
||||||
@Query('perPage') perPage = '10',
|
|
||||||
): Promise<SaleInvoicesServiceFindAllResponseDto> {
|
): Promise<SaleInvoicesServiceFindAllResponseDto> {
|
||||||
const filter: ConsumerSaleInvoicesFilterDto = {
|
return this.service.findAll(consumerId, query)
|
||||||
page: Number(page) || 1,
|
|
||||||
perPage: Number(perPage) || 10,
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.service.findAll(consumerId, filter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
|
|||||||
@@ -59,11 +59,7 @@ export class SaleInvoicesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findAll(consumer_id: string, filter: ConsumerSaleInvoicesFilterDto) {
|
async findAll(consumer_id: string, filter: ConsumerSaleInvoicesFilterDto) {
|
||||||
const invoicesWhere: SalesInvoiceWhereInput = {
|
const invoicesWhere = this.buildFindAllWhere(consumer_id, filter)
|
||||||
consumer_account: {
|
|
||||||
consumer_id,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
const normalizedPageValue = Number(filter.page ?? 1)
|
const normalizedPageValue = Number(filter.page ?? 1)
|
||||||
const normalizedPage = Number.isFinite(normalizedPageValue)
|
const normalizedPage = Number.isFinite(normalizedPageValue)
|
||||||
? Math.max(1, Math.floor(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) {
|
async findOne(consumer_id: string, id: string) {
|
||||||
const invoicesWhere: SalesInvoiceWhereUniqueInput = {
|
const invoicesWhere: SalesInvoiceWhereUniqueInput = {
|
||||||
id,
|
id,
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ export class PosService {
|
|||||||
constructor(private readonly prisma: PrismaService) {}
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
async getInfo(pos_id: string) {
|
async getInfo(pos_id: string) {
|
||||||
|
console.log('pos_id', pos_id)
|
||||||
|
|
||||||
const pos = await this.prisma.pos.findUniqueOrThrow({
|
const pos = await this.prisma.pos.findUniqueOrThrow({
|
||||||
where: {
|
where: {
|
||||||
id: pos_id,
|
id: pos_id,
|
||||||
|
|||||||
Reference in New Issue
Block a user