feat: add stock keeping unit management with create, update, and retrieval functionalities

- Implemented CreateStockKeepingUnitDto for creating stock keeping units.
- Added StockKeepingUnitsService for handling business logic related to stock keeping units.
- Created StockKeepingUnitsController to manage HTTP requests for stock keeping units.
- Developed UpdateStockKeepingUnitDto for updating existing stock keeping units.
- Introduced StockKeepingUnitsServiceFindAllResponseDto for response structure.
- Established stock keeping units module for encapsulation of related components.

feat: enhance sales invoice fiscal management with new endpoints

- Created SalesInvoicesFilterDto for filtering sales invoices.
- Implemented PosSalesInvoiceFiscalController for managing fiscal operations on sales invoices.
- Developed PosSalesInvoiceFiscalService to handle fiscal logic and interactions.
- Added methods for sending, retrying, and checking the status of fiscal invoices.
- Integrated error handling and response mapping for fiscal operations.
This commit is contained in:
2026-05-01 19:43:59 +03:30
parent a68a7f594d
commit ad470d2166
91 changed files with 8973 additions and 2469 deletions
+2
View File
@@ -9,6 +9,7 @@ import { AdminGuildsModule } from './guilds/guilds.module'
import { AdminLicensesModule } from './licenses/licenses.module'
import { AdminPartnersModule } from './partners/partners.module'
import { AdminProvidersModule } from './providers/providers.module'
import { AdminStockKeepingUnitsModule } from './stock-keeping-units/stock-keeping-units.module'
import { AdminTranslateModule } from './translate/translate.module'
import { AdminUserAccountsModule } from './users/accounts/accounts.module'
import { AdminUsersModule } from './users/users.module'
@@ -25,6 +26,7 @@ import { AdminUsersModule } from './users/users.module'
AdminGuildsModule,
AdminDeviceBrandsModule,
AdminDevicesModule,
AdminStockKeepingUnitsModule,
AdminLicensesModule,
AdminConsumersModule,
],
@@ -1,23 +1,23 @@
import { GoodPricingModel, UnitType } from '@/generated/prisma/enums'
import { GoodPricingModel } from '@/generated/prisma/enums'
import { ApiProperty, PartialType } from '@nestjs/swagger'
import { IsEnum, IsOptional, IsString } from 'class-validator'
export class CreateGuildGoodDto {
@ApiProperty({ required: true })
@IsString()
@ApiProperty()
name: string
@IsString()
@ApiProperty()
sku: string
@IsString()
@ApiProperty({ required: true })
@IsString()
sku_id: string
@ApiProperty({ required: true })
@IsString()
category_id: string
@IsEnum(UnitType)
@ApiProperty({ required: true, enum: UnitType })
unit_type: UnitType
@ApiProperty({ required: true })
@IsString()
measure_unit_id: string
@IsEnum(GoodPricingModel)
@ApiProperty({ required: true, enum: GoodPricingModel })
@@ -17,10 +17,20 @@ export class GoodsService {
id: true,
name: true,
pricing_model: true,
unit_type: true,
image_url: true,
sku: true,
description: true,
sku: {
select: {
id: true,
name: true,
},
},
measure_unit: {
select: {
id: true,
name: true,
},
},
category: {
select: {
id: true,
@@ -62,7 +72,7 @@ export class GoodsService {
}
async create(data: CreateGuildGoodDto, file: Express.Multer.File) {
const { category_id, ...rest } = data
const { category_id, measure_unit_id, sku_id, ...rest } = data
const good = await this.prisma.$transaction(async tx => {
let image_url = ''
@@ -79,6 +89,16 @@ export class GoodsService {
...rest,
is_default_guild_good: true,
image_url,
sku: {
connect: {
id: sku_id,
},
},
measure_unit: {
connect: {
id: measure_unit_id,
},
},
category: {
connect: {
id: category_id,
@@ -93,7 +113,7 @@ export class GoodsService {
}
async update(id: string, data: UpdateGuildGoodDto, file: Express.Multer.File) {
const { category_id, ...rest } = data
const { category_id, measure_unit_id, sku_id, ...rest } = data
const good = await this.prisma.$transaction(async tx => {
let image_url = ''
@@ -120,6 +140,16 @@ export class GoodsService {
...rest,
is_default_guild_good: true,
image_url,
sku: {
connect: {
id: sku_id,
},
},
measure_unit: {
connect: {
id: measure_unit_id,
},
},
category: {
connect: {
id: category_id,
@@ -0,0 +1,32 @@
import { SKUGuildType } from '@/generated/prisma/enums'
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'
import { Type } from 'class-transformer'
import { IsBoolean, IsEnum, IsNumber, IsString, Min } from 'class-validator'
export class CreateStockKeepingUnitDto {
@ApiProperty()
@IsString()
code: string
@ApiProperty()
@IsString()
name: string
@ApiProperty()
@Type(() => Number)
@IsNumber()
@Min(0)
VAT: number
@ApiPropertyOptional({ enum: SKUGuildType, default: SKUGuildType.GOLD })
@IsEnum(SKUGuildType)
type: SKUGuildType = SKUGuildType.GOLD
@ApiPropertyOptional({ default: true })
@IsBoolean()
is_public: boolean = true
@ApiPropertyOptional({ default: true })
@IsBoolean()
is_domestic: boolean = true
}
@@ -0,0 +1,11 @@
import type { StockKeepingUnitsService } from '../stock-keeping-units.service'
export type StockKeepingUnitsServiceCreateResponseDto = Awaited<
ReturnType<StockKeepingUnitsService['create']>
>
export type StockKeepingUnitsServiceFindAllResponseDto = Awaited<
ReturnType<StockKeepingUnitsService['findAll']>
>
export type StockKeepingUnitsServiceUpdateResponseDto = Awaited<
ReturnType<StockKeepingUnitsService['update']>
>
@@ -0,0 +1,4 @@
import { PartialType } from '@nestjs/swagger'
import { CreateStockKeepingUnitDto } from './create-stock-keeping-unit.dto'
export class UpdateStockKeepingUnitDto extends PartialType(CreateStockKeepingUnitDto) {}
@@ -0,0 +1,36 @@
import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common'
import { ApiTags } from '@nestjs/swagger'
import type {
StockKeepingUnitsServiceCreateResponseDto,
StockKeepingUnitsServiceFindAllResponseDto,
StockKeepingUnitsServiceUpdateResponseDto,
} from './dto/stock-keeping-units-response.dto'
import { CreateStockKeepingUnitDto } from './dto/create-stock-keeping-unit.dto'
import { UpdateStockKeepingUnitDto } from './dto/update-stock-keeping-unit.dto'
import { StockKeepingUnitsService } from './stock-keeping-units.service'
@ApiTags('AdminStockKeepingUnits')
@Controller('admin/stock-keeping-units')
export class StockKeepingUnitsController {
constructor(private readonly service: StockKeepingUnitsService) {}
@Get()
async findAll(): Promise<StockKeepingUnitsServiceFindAllResponseDto> {
return this.service.findAll()
}
@Post()
async create(
@Body() data: CreateStockKeepingUnitDto,
): Promise<StockKeepingUnitsServiceCreateResponseDto> {
return this.service.create(data)
}
@Patch(':id')
async update(
@Param('id') id: string,
@Body() data: UpdateStockKeepingUnitDto,
): Promise<StockKeepingUnitsServiceUpdateResponseDto> {
return this.service.update(id, data)
}
}
@@ -0,0 +1,11 @@
import { PrismaModule } from '@/prisma/prisma.module'
import { Module } from '@nestjs/common'
import { StockKeepingUnitsController } from './stock-keeping-units.controller'
import { StockKeepingUnitsService } from './stock-keeping-units.service'
@Module({
imports: [PrismaModule],
controllers: [StockKeepingUnitsController],
providers: [StockKeepingUnitsService],
})
export class AdminStockKeepingUnitsModule {}
@@ -0,0 +1,30 @@
import { PrismaService } from '@/prisma/prisma.service'
import { Injectable } from '@nestjs/common'
import { ResponseMapper } from 'common/response/response-mapper'
import { CreateStockKeepingUnitDto } from './dto/create-stock-keeping-unit.dto'
import { UpdateStockKeepingUnitDto } from './dto/update-stock-keeping-unit.dto'
@Injectable()
export class StockKeepingUnitsService {
constructor(private readonly prisma: PrismaService) {}
async findAll() {
const items = await this.prisma.stockKeepingUnits.findMany({
orderBy: { created_at: 'desc' },
})
return ResponseMapper.list(items)
}
async create(data: CreateStockKeepingUnitDto) {
const item = await this.prisma.stockKeepingUnits.create({ data })
return ResponseMapper.create(item)
}
async update(id: string, data: UpdateStockKeepingUnitDto) {
const item = await this.prisma.stockKeepingUnits.update({
where: { id },
data,
})
return ResponseMapper.update(item)
}
}