Add products and sales management modules with database schema and validation

- Introduced `ProductsModule` to manage product data, including read and write controllers.
- Created database migrations for the `products`, `sales_requests`, `sales_orders`, `sales_invoices`, and related tables, including constraints and unique indexes.
- Implemented validation for product fields such as code, name, unit, and brand with corresponding utility functions.
- Developed service and repository layers for handling product and sales data operations.
- Added unit tests for the products and sales services, repositories, and controllers to ensure functionality and correctness.
- Updated application module to include the new `ProductsModule` and related sales modules for better organization.
This commit is contained in:
shancheas
2026-08-25 09:54:16 +07:00
parent ddbe8a9ef8
commit 34d4f2c120
82 changed files with 12609 additions and 2 deletions
@@ -0,0 +1,64 @@
import { Controller, Get, Param, ParseUUIDPipe, Query } from '@nestjs/common';
import {
ApiBearerAuth,
ApiForbiddenResponse,
ApiNotFoundResponse,
ApiOkResponse,
ApiOperation,
ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { RequirePrivilege } from '../../../common/decorators/require-privilege.decorator';
import {
Pagination,
type PaginationResponse,
PaginationMetaDto,
} from '../../../common/http/response';
import { BEARER_AUTH_NAME } from '../../../common/swagger/setup-swagger';
import { SalesOrderDto, ListSalesOrdersQueryDto } from './dto/sales-order.dto';
import { SalesOrdersService } from './sales-orders.service';
export const SALES_ORDER_PRIVILEGE_KEY = 'SALES.ORDER';
@ApiTags('sales-orders')
@ApiBearerAuth(BEARER_AUTH_NAME)
@Controller('sales-orders')
export class SalesOrdersReadController {
constructor(private readonly salesOrdersService: SalesOrdersService) {}
@Get()
@Pagination()
@RequirePrivilege(SALES_ORDER_PRIVILEGE_KEY, 'view')
@ApiOperation({ summary: 'List sales orders' })
@ApiOkResponse({
schema: {
properties: {
data: {
type: 'array',
items: { $ref: '#/components/schemas/SalesOrderDto' },
},
meta: { $ref: '#/components/schemas/PaginationMetaDto' },
},
},
})
@ApiUnauthorizedResponse()
@ApiForbiddenResponse()
list(
@Query() query: ListSalesOrdersQueryDto,
): Promise<PaginationResponse<SalesOrderDto>> {
return this.salesOrdersService.list(query);
}
@Get(':id')
@RequirePrivilege(SALES_ORDER_PRIVILEGE_KEY, 'view')
@ApiOperation({ summary: 'Get sales order detail' })
@ApiOkResponse({ type: SalesOrderDto })
@ApiNotFoundResponse()
@ApiUnauthorizedResponse()
@ApiForbiddenResponse()
findOne(@Param('id', ParseUUIDPipe) id: string): Promise<SalesOrderDto> {
return this.salesOrdersService.findById(id);
}
}
void PaginationMetaDto;