feat(customers): enhance customer retrieval with filtering options

- Updated `findAll` method in `CustomersController` to accept filtering parameters.
- Implemented filtering logic in `CustomersService` to retrieve customers based on type and search query.
- Added `PosCustomerFilterDto` for query validation.
- Updated customer-related DTOs to make fields optional and added length validation where necessary.
- Modified customer-related logic in `sales-invoice-tsp.utils.ts` to accommodate new DTO structure.
- Added unique constraints to `customer_individuals` and `customer_legal` tables in the database migration.
- Removed commented-out code in `PosMiddleware` for cleaner codebase.
- Set default value for `is_default_guild_good` to false in `OwnedGoodsService`.
This commit is contained in:
2026-06-03 18:00:06 +03:30
parent b2d8fdc8a0
commit 5ce560ce97
19 changed files with 946 additions and 613 deletions
+122 -3
View File
@@ -1,10 +1,129 @@
import { IPosPayload } from '@/common/models'
import { ResponseMapper } from '@/common/response/response-mapper'
import { CustomerType } from '@/generated/prisma/enums'
import { CustomerSelect, CustomerWhereInput } from '@/generated/prisma/models'
import { PrismaService } from '@/prisma/prisma.service'
import { Injectable } from '@nestjs/common'
import { PosCustomerFilterDto } from './dto/customer-filter.dto'
@Injectable()
export class CustomersService {
findAll() {
// TODO: Implement fetching all customers
return []
constructor(private prisma: PrismaService) {}
async findAll(posInfo: IPosPayload, query: PosCustomerFilterDto) {
const { type, q } = query
const where: CustomerWhereInput = {
type,
}
const select: CustomerSelect = {
id: true,
}
if (type === CustomerType.LEGAL) {
where.legal = {
business_activity_id: posInfo.business_id,
}
select.legal = {
select: {
name: true,
economic_code: true,
postal_code: true,
registration_number: true,
},
}
if (q) {
where.legal = {
...where.legal,
OR: [
{
name: {
contains: q,
},
},
{
economic_code: {
contains: q,
},
},
{
postal_code: {
contains: q,
},
},
{
registration_number: {
contains: q,
},
},
],
}
}
} else if (type === CustomerType.INDIVIDUAL) {
where.individual = {
business_activity_id: posInfo.business_id,
}
select.individual = {
select: {
first_name: true,
last_name: true,
economic_code: true,
postal_code: true,
mobile_number: true,
national_id: true,
},
}
if (q) {
where.individual = {
...where.individual,
OR: [
{
first_name: {
contains: q,
},
},
{
last_name: {
contains: q,
},
},
{
economic_code: {
contains: q,
},
},
{
postal_code: {
contains: q,
},
},
{
mobile_number: {
contains: q,
},
},
{
national_id: {
contains: q,
},
},
],
}
}
}
const customers = await this.prisma.customer.findMany({
where,
take: 20,
orderBy: {
created_at: 'desc',
},
select: {
id: true,
type: true,
created_at: true,
updated_at: true,
},
})
return ResponseMapper.list(customers)
}
findOne(id: number) {