diff --git a/src/common/exceptions/biz.exception.ts b/src/common/exceptions/biz.exception.ts index 11275b9..7b00f13 100644 --- a/src/common/exceptions/biz.exception.ts +++ b/src/common/exceptions/biz.exception.ts @@ -26,7 +26,7 @@ export class BusinessException extends HttpException { code, message }), - HttpStatus.OK + HttpStatus.BAD_REQUEST ); this.errorCode = Number(code); diff --git a/src/constants/enum/index.ts b/src/constants/enum/index.ts index 257a9dd..70ec17b 100644 --- a/src/constants/enum/index.ts +++ b/src/constants/enum/index.ts @@ -21,8 +21,9 @@ export enum MaterialsInOrOutEnum { // 系统参数key export enum ParamConfigEnum { - InventoryNumberPrefixIn = 'inventory_number_prefix_in', - InventoryNumberPrefixOut = 'inventory_number_prefix_out', + InventoryNumberPrefix = 'inventory_number_prefix', + InventoryInOutNumberPrefixIn = 'inventory_inout_number_prefix_in', + InventoryInOutNumberPrefixOut = 'inventory_inout_number_prefix_out', ProductNumberPrefix = 'product_number_prefix' } @@ -32,3 +33,10 @@ export enum ContractStatusEnum { Approved = 1, // 已通过 Rejected = 2 // 已拒绝 } + +// 库存查询剩余咋黄台 +export enum HasInventoryStatusEnum { + All = 0, // 全部 + Yes = 1, // 有库存 + No = 2 // 无库存 +} diff --git a/src/modules/auth/guards/jwt-auth.guard.ts b/src/modules/auth/guards/jwt-auth.guard.ts index c42ff73..4349a13 100644 --- a/src/modules/auth/guards/jwt-auth.guard.ts +++ b/src/modules/auth/guards/jwt-auth.guard.ts @@ -1,4 +1,4 @@ -import { ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common'; +import { ExecutionContext, HttpException, HttpStatus, Injectable, UnauthorizedException } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; import { FastifyRequest } from 'fastify'; @@ -72,7 +72,7 @@ export class JwtAuthGuard extends AuthGuard(AuthStrategy.JWT) { const pv = await this.authService.getPasswordVersionByUid(request.user.uid); if (pv !== `${request.user.pv}`) { // 密码版本不一致,登录期间已更改过密码 - throw new BusinessException(ErrorEnum.INVALID_LOGIN); + throw new HttpException(ErrorEnum.INVALID_LOGIN,HttpStatus.UNAUTHORIZED); } // 不允许多端登录 diff --git a/src/modules/common/base.service.ts b/src/modules/common/base.service.ts index 7b47117..7cb472d 100644 --- a/src/modules/common/base.service.ts +++ b/src/modules/common/base.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; @Injectable() export class BaseService { - generateInventoryNumber(): string { + generateInventoryInOutNumber(): string { // Generate a random inventory number return Math.floor(Math.random() * 1000000).toString(); } diff --git a/src/modules/materials_inventory/in_out/materials_in_out.controller.ts b/src/modules/materials_inventory/in_out/materials_in_out.controller.ts index 406a3e5..2bf709b 100644 --- a/src/modules/materials_inventory/in_out/materials_in_out.controller.ts +++ b/src/modules/materials_inventory/in_out/materials_in_out.controller.ts @@ -6,7 +6,11 @@ import { MaterialsInOutService } from './materials_in_out.service'; import { MaterialsInOutEntity } from './materials_in_out.entity'; import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator'; import { definePermission, Perm } from '~/modules/auth/decorators/permission.decorator'; -import { MaterialsInOutQueryDto, MaterialsInOutDto, MaterialsInOutUpdateDto } from './materials_in_out.dto'; +import { + MaterialsInOutQueryDto, + MaterialsInOutDto, + MaterialsInOutUpdateDto +} from './materials_in_out.dto'; export const permissions = definePermission('materials_inventory:history_in_out', { LIST: 'list', @@ -40,8 +44,8 @@ export class MaterialsInOutController { @Post() @ApiOperation({ summary: '新增原材料出入库记录' }) @Perm(permissions.CREATE) - async create(@Body() dto: MaterialsInOutDto): Promise { - await this.materialsInOutService.create(dto); + async create(@Body() dto: MaterialsInOutDto): Promise { + return this.materialsInOutService.create(dto); } @Put(':id') diff --git a/src/modules/materials_inventory/in_out/materials_in_out.dto.ts b/src/modules/materials_inventory/in_out/materials_in_out.dto.ts index 767a29c..a2f7fb7 100644 --- a/src/modules/materials_inventory/in_out/materials_in_out.dto.ts +++ b/src/modules/materials_inventory/in_out/materials_in_out.dto.ts @@ -29,14 +29,14 @@ export class MaterialsInOutDto { projectId?: number; @ApiProperty({ description: '产品Id' }) - @ValidateIf(o => !o.inventoryNumber) + @ValidateIf(o => !o.inventoryInOutNumber) @IsNumber() productId: number; @ApiProperty({ description: '原材料库存编号' }) @IsOptional() @IsString() - inventoryNumber: string; + inventoryInOutNumber: string; @ApiProperty({ description: '库存id(产品和单价双主键决定一条库存)' }) @IsOptional() @@ -80,6 +80,11 @@ export class MaterialsInOutDto { @IsString() issuanceNumber: string; + @ApiProperty({ description: '库存位置' }) + @IsOptional() + @IsString() + position: string; + @IsOptional() @IsString() @ApiProperty({ description: '备注' }) @@ -98,11 +103,12 @@ export class MaterialsInOutQueryDto extends PagerDto { // @IsString() @Transform(params => { // 开始和结束时间用的是一天的开始和一天的结束的时分秒 - const date = params.value; - return [ - date ? `${formatToDate(dayjs(date).startOf('month'))} 00:00:00` : null, - date ? `${formatToDate(dayjs(date).endOf('month'))} 23:59:59` : null - ]; + return params.value + ? [ + params.value[0] ? `${formatToDate(params.value[0], 'YYYY-MM-DD')} 00:00:00` : null, + params.value[1] ? `${formatToDate(params.value[1], 'YYYY-MM-DD')} 23:59:59` : null + ] + : []; }) time?: string[]; @@ -129,7 +135,7 @@ export class MaterialsInOutQueryDto extends PagerDto { @ApiProperty({ description: '原材料库存编号' }) @IsOptional() @IsString() - inventoryNumber?: string; + inventoryInOutNumber?: string; @IsOptional() @IsString() diff --git a/src/modules/materials_inventory/in_out/materials_in_out.entity.ts b/src/modules/materials_inventory/in_out/materials_in_out.entity.ts index eb6ab98..56c4057 100644 --- a/src/modules/materials_inventory/in_out/materials_in_out.entity.ts +++ b/src/modules/materials_inventory/in_out/materials_in_out.entity.ts @@ -19,16 +19,17 @@ import { ProductEntity } from '~/modules/product/product.entity'; import { ProjectEntity } from '~/modules/project/project.entity'; import { ParamConfigEntity } from '~/modules/system/param-config/param-config.entity'; import { Storage } from '~/modules/tools/storage/storage.entity'; +import { MaterialsInventoryEntity } from '../materials_inventory.entity'; @Entity({ name: 'materials_in_out' }) export class MaterialsInOutEntity extends CommonEntity { @Column({ - name: 'inventory_number', + name: 'inventory_inout_number', type: 'varchar', length: 50, - comment: '原材料库存编号' + comment: '原材料出入库编号' }) - @ApiProperty({ description: '原材料库存编号' }) - inventoryNumber: string; + @ApiProperty({ description: '原材料出入库编号' }) + inventoryInOutNumber: string; @Column({ name: 'product_id', @@ -38,6 +39,14 @@ export class MaterialsInOutEntity extends CommonEntity { @ApiProperty({ description: '产品' }) productId: number; + @Column({ + name: 'inventory_id', + type: 'int', + comment: '库存' + }) + @ApiProperty({ description: '库存' }) + inventoryId: number; + @Column({ name: 'in_or_out', type: 'tinyint', @@ -127,4 +136,8 @@ export class MaterialsInOutEntity extends CommonEntity { inverseJoinColumn: { name: 'file_id', referencedColumnName: 'id' } }) files: Relation; + + @ManyToOne(() => MaterialsInventoryEntity) + @JoinColumn({ name: 'inventory_id' }) + inventory: MaterialsInventoryEntity; } diff --git a/src/modules/materials_inventory/in_out/materials_in_out.service.ts b/src/modules/materials_inventory/in_out/materials_in_out.service.ts index 617a80d..82e4857 100644 --- a/src/modules/materials_inventory/in_out/materials_in_out.service.ts +++ b/src/modules/materials_inventory/in_out/materials_in_out.service.ts @@ -43,26 +43,7 @@ export class MaterialsInOutService { isCreateOut, ...ext }: MaterialsInOutQueryDto): Promise> { - const sqb = this.materialsInOutRepository - .createQueryBuilder('materialsInOut') - .leftJoin('materialsInOut.files', 'files') - .leftJoin('materialsInOut.project', 'project') - .leftJoin('materialsInOut.product', 'product') - .leftJoin('product.unit', 'unit') - .leftJoin('product.files', 'productFiles') - .leftJoin('product.company', 'company') - .addSelect([ - 'files.id', - 'files.path', - 'project.name', - 'product.name', - 'product.productSpecification', - 'product.productNumber', - 'productFiles.id', - 'productFiles.path', - 'unit.label', - 'company.name' - ]) + const sqb = this.buildSearchQuery() .where(fieldSearch(ext)) .andWhere('materialsInOut.isDelete = 0') .addOrderBy('materialsInOut.createdAt', 'DESC'); @@ -85,25 +66,63 @@ export class MaterialsInOutService { return pageData; } + buildSearchQuery() { + return this.materialsInOutRepository + .createQueryBuilder('materialsInOut') + .leftJoin('materialsInOut.files', 'files') + .leftJoin('materialsInOut.project', 'project') + .leftJoin('materialsInOut.product', 'product') + .leftJoin('materialsInOut.inventory', 'inventory') + .leftJoin('product.unit', 'unit') + .leftJoin('product.files', 'productFiles') + .leftJoin('product.company', 'company') + .addSelect([ + 'inventory.id', + 'inventory.position', + 'files.id', + 'files.path', + 'project.name', + 'product.name', + 'product.productSpecification', + 'product.productNumber', + 'productFiles.id', + 'productFiles.path', + 'unit.label', + 'company.name' + ]); + } /** * 新增 */ - async create(dto: MaterialsInOutDto): Promise { - let { inOrOut, inventoryNumber, projectId, inventoryId } = dto; - inventoryNumber = await this.generateInventoryNumber(inOrOut); + async create(dto: MaterialsInOutDto): Promise { + let { + inOrOut, + inventoryInOutNumber, + projectId, + inventoryId, + position, + unitPrice, + quantity, + productId + } = dto; + inventoryInOutNumber = await this.generateInventoryInOutNumber(inOrOut); + let newRecordId; await this.entityManager.transaction(async manager => { - // 1.生成出入库记录 - const { productId, quantity, unitPrice } = await manager.save(MaterialsInOutEntity, { - ...this.materialsInOutRepository.create(dto), - inventoryNumber - }); - // 2.更新增减库存 - await ( + delete dto.position; + // 1.更新增减库存 + const inventoryEntity = await ( Object.is(inOrOut, MaterialsInOrOutEnum.In) - ? this.materialsInventoryService.inInventory - : this.materialsInventoryService.outInventory - )({ productId, quantity, unitPrice, projectId, inventoryId }, manager); + ? this.materialsInventoryService.inInventory.bind(this.materialsInventoryService) + : this.materialsInventoryService.outInventory.bind(this.materialsInventoryService) + )({ productId, quantity, unitPrice, projectId, inventoryId, position }, manager); + // 2.生成出入库记录 + const { id } = await manager.save(MaterialsInOutEntity, { + ...this.materialsInOutRepository.create({ ...dto, inventoryId: inventoryEntity?.id }), + inventoryInOutNumber + }); + newRecordId = id; }); + return newRecordId; } /** @@ -138,8 +157,8 @@ export class MaterialsInOutService { } await ( Object.is(data.inOrOut, MaterialsInOrOutEnum.In) - ? this.materialsInventoryService.inInventory - : this.materialsInventoryService.outInventory + ? this.materialsInventoryService.inInventory.bind(this.materialsInventoryService) + : this.materialsInventoryService.outInventory.bind(this.materialsInventoryService) )( { productId: entity.productId, @@ -189,7 +208,6 @@ export class MaterialsInOutService { manager ); } - // 完成所有业务逻辑后,更新出入库记录 await manager.update(MaterialsInOutEntity, id, { ...data @@ -232,8 +250,8 @@ export class MaterialsInOutService { // 更新库存 await ( Object.is(entity.inOrOut, MaterialsInOrOutEnum.In) - ? this.materialsInventoryService.outInventory - : this.materialsInventoryService.inInventory + ? this.materialsInventoryService.outInventory.bind(this.materialsInventoryService) + : this.materialsInventoryService.inInventory.bind(this.materialsInventoryService) )( { productId: entity.productId, @@ -253,8 +271,7 @@ export class MaterialsInOutService { * 获取单个出入库信息 */ async info(id: number) { - const info = await this.materialsInOutRepository - .createQueryBuilder('materialsInOut') + const info = await this.buildSearchQuery() .where({ id }) @@ -288,30 +305,30 @@ export class MaterialsInOutService { } /** - * 生成库存单号 - * @returns 库存单号 + * 生成库存出入库单号 + * @returns 库存出入库单号 */ - async generateInventoryNumber(inOrOut: MaterialsInOrOutEnum = MaterialsInOrOutEnum.In) { + async generateInventoryInOutNumber(inOrOut: MaterialsInOrOutEnum = MaterialsInOrOutEnum.In) { const prefix = ( await this.paramConfigRepository.findOne({ where: { key: inOrOut - ? ParamConfigEnum.InventoryNumberPrefixOut - : ParamConfigEnum.InventoryNumberPrefixIn + ? ParamConfigEnum.InventoryInOutNumberPrefixOut + : ParamConfigEnum.InventoryInOutNumberPrefixIn } }) )?.value || ''; const lastMaterial = await this.materialsInOutRepository .createQueryBuilder('materialsInOut') .select( - `MAX(CAST(REPLACE(materialsInOut.inventoryNumber, '${prefix}', '') AS UNSIGNED))`, - 'maxInventoryNumber' + `MAX(CAST(REPLACE(materialsInOut.inventoryInOutNumber, '${prefix}', '') AS UNSIGNED))`, + 'maxInventoryInOutNumber' ) .where('materialsInOut.inOrOut = :inOrOut', { inOrOut }) .getRawOne(); - const lastNumber = lastMaterial.maxInventoryNumber - ? parseInt(lastMaterial.maxInventoryNumber.replace(prefix, '')) + const lastNumber = lastMaterial.maxInventoryInOutNumber + ? parseInt(lastMaterial.maxInventoryInOutNumber.replace(prefix, '')) : 0; const newNumber = lastNumber + 1 < 1000 ? 1000 : lastNumber + 1; return `${prefix}${newNumber}`; diff --git a/src/modules/materials_inventory/materials_inventory.dto.ts b/src/modules/materials_inventory/materials_inventory.dto.ts index 20bfd68..f4111ee 100644 --- a/src/modules/materials_inventory/materials_inventory.dto.ts +++ b/src/modules/materials_inventory/materials_inventory.dto.ts @@ -3,6 +3,7 @@ import { IsArray, IsDate, IsDateString, + IsEnum, IsIn, IsInt, IsNumber, @@ -16,6 +17,7 @@ import { Storage } from '../tools/storage/storage.entity'; import { Transform } from 'class-transformer'; import dayjs from 'dayjs'; import { formatToDate } from '~/utils'; +import { HasInventoryStatusEnum } from '~/constants/enum'; export class MaterialsInventoryDto {} @@ -23,7 +25,22 @@ export class MaterialsInventoryUpdateDto extends PartialType(MaterialsInventoryD export class MaterialsInventoryQueryDto extends IntersectionType( PagerDto, PartialType(MaterialsInventoryDto) -) {} +) { + @ApiProperty({ description: '产品名' }) + @IsOptional() + @IsString() + product: string; + + @ApiProperty({ description: '关键字' }) + @IsOptional() + @IsString() + keyword: string; + + @ApiProperty({ description: '产品名' }) + @IsOptional() + @IsEnum(HasInventoryStatusEnum) + isHasInventory: HasInventoryStatusEnum; +} export class MaterialsInventoryExportDto { @ApiProperty({ description: '项目' }) @IsOptional() diff --git a/src/modules/materials_inventory/materials_inventory.entity.ts b/src/modules/materials_inventory/materials_inventory.entity.ts index b8c509a..69dfc7b 100644 --- a/src/modules/materials_inventory/materials_inventory.entity.ts +++ b/src/modules/materials_inventory/materials_inventory.entity.ts @@ -1,8 +1,18 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { Column, Entity, JoinColumn, JoinTable, ManyToMany, ManyToOne, Relation } from 'typeorm'; +import { ApiHideProperty, ApiProperty } from '@nestjs/swagger'; +import { + Column, + Entity, + JoinColumn, + JoinTable, + ManyToMany, + ManyToOne, + OneToMany, + Relation +} from 'typeorm'; import { CommonEntity } from '~/common/entity/common.entity'; import { ProductEntity } from '../product/product.entity'; import { ProjectEntity } from '../project/project.entity'; +import { MaterialsInOutEntity } from './in_out/materials_in_out.entity'; @Entity({ name: 'materials_inventory' }) export class MaterialsInventoryEntity extends CommonEntity { @@ -22,6 +32,16 @@ export class MaterialsInventoryEntity extends CommonEntity { @ApiProperty({ description: '产品' }) productId: number; + @Column({ + name: 'position', + type: 'varchar', + length: 255, + nullable: true, + comment: '库存位置' + }) + @ApiProperty({ description: '库存位置' }) + position: string; + @Column({ name: 'quantity', type: 'int', @@ -57,4 +77,17 @@ export class MaterialsInventoryEntity extends CommonEntity { @ManyToOne(() => ProductEntity) @JoinColumn({ name: 'product_id' }) product: ProductEntity; + + @Column({ + name: 'inventory_number', + type: 'varchar', + length: 50, + comment: '库存编号' + }) + @ApiProperty({ description: '库存编号' }) + inventoryNumber: string; + + @ApiHideProperty() + @OneToMany(() => MaterialsInOutEntity, inout => inout.inventory) + materialsInOuts: Relation; } diff --git a/src/modules/materials_inventory/materials_inventory.service.ts b/src/modules/materials_inventory/materials_inventory.service.ts index 1a144c3..435bd9b 100644 --- a/src/modules/materials_inventory/materials_inventory.service.ts +++ b/src/modules/materials_inventory/materials_inventory.service.ts @@ -16,14 +16,15 @@ import dayjs from 'dayjs'; import { MaterialsInOutEntity } from './in_out/materials_in_out.entity'; import { fieldSearch } from '~/shared/database/field-search'; import { groupBy, sum, uniqBy } from 'lodash'; -import { MaterialsInOrOutEnum } from '~/constants/enum'; +import { HasInventoryStatusEnum, MaterialsInOrOutEnum, ParamConfigEnum } from '~/constants/enum'; import { ProjectEntity } from '../project/project.entity'; import { calcNumber } from '~/utils'; import { BusinessException } from '~/common/exceptions/biz.exception'; import { ErrorEnum } from '~/constants/error-code.constant'; +import { ParamConfigEntity } from '../system/param-config/param-config.entity'; +import { isDefined } from 'class-validator'; @Injectable() export class MaterialsInventoryService { - const; constructor( @InjectEntityManager() private entityManager: EntityManager, @InjectRepository(MaterialsInventoryEntity) @@ -31,7 +32,9 @@ export class MaterialsInventoryService { @InjectRepository(MaterialsInOutEntity) private materialsInOutRepository: Repository, @InjectRepository(ProjectEntity) - private projectRepository: Repository + private projectRepository: Repository, + @InjectRepository(ParamConfigEntity) + private paramConfigRepository: Repository ) {} /** @@ -236,7 +239,7 @@ export class MaterialsInventoryService { ); number++; sheet.addRow([ - `${inRecord.inventoryNumber || ''}`, + `${inRecord.inventoryInOutNumber || ''}`, inRecord.product.company.name || '', inRecord.product.name || '', inRecord.product.unit.label || '', @@ -312,7 +315,10 @@ export class MaterialsInventoryService { */ async findAll({ page, - pageSize + pageSize, + product, + keyword, + isHasInventory }: MaterialsInventoryQueryDto): Promise> { const queryBuilder = this.materialsInventoryRepository .createQueryBuilder('materialsInventory') @@ -322,13 +328,34 @@ export class MaterialsInventoryService { .leftJoin('product.company', 'company') .addSelect([ 'project.name', + 'project.id', + 'unit.id', 'unit.label', + 'company.id', 'company.name', + 'product.id', 'product.name', 'product.productSpecification', 'product.productNumber' ]) .where('materialsInventory.isDelete = 0'); + if (product) { + queryBuilder.andWhere('product.name like :product', { product: `%${product}%` }); + } + if (keyword) { + queryBuilder.andWhere( + '(materialsInventory.inventoryNumber like :keyword or product.name like :keyword or product.productNumber like :keyword or product.productSpecification like :keyword)', + { + keyword: `%${keyword}%` + } + ); + } + if (isHasInventory == HasInventoryStatusEnum.Yes) { + queryBuilder.andWhere('materialsInventory.quantity > 0'); + } + if (isHasInventory == HasInventoryStatusEnum.No) { + queryBuilder.andWhere('materialsInventory.quantity = 0'); + } return paginate(queryBuilder, { page, pageSize @@ -361,6 +388,7 @@ export class MaterialsInventoryService { */ async inInventory( data: { + position?: string; projectId: number; productId: number; quantity: number; @@ -368,8 +396,15 @@ export class MaterialsInventoryService { changedUnitPrice?: number; }, manager: EntityManager - ): Promise { - const { projectId, productId, quantity: inQuantity, unitPrice, changedUnitPrice } = data; + ): Promise { + const { + projectId, + productId, + quantity: inQuantity, + unitPrice, + changedUnitPrice, + position + } = data; const exsitedInventory = await manager.findOne(MaterialsInventoryEntity, { where: { projectId, productId, unitPrice }, // 根据项目,产品,价格查出之前的实时库存情况 @@ -378,13 +413,16 @@ export class MaterialsInventoryService { // 若不存在库存,直接新增库存 if (!exsitedInventory) { - await manager.insert(MaterialsInventoryEntity, { + const inventoryNumber = await this.generateInventoryNumber(); + const { raw } = await manager.insert(MaterialsInventoryEntity, { projectId, productId, unitPrice, + inventoryNumber, + position, quantity: inQuantity }); - return; + return manager.findOne(MaterialsInventoryEntity, { where: { id: raw.insertId } }); } // 若该项目存在库存,则该项目该产品的库存增加 let { quantity, id } = exsitedInventory; @@ -396,6 +434,8 @@ export class MaterialsInventoryService { quantity: newQuantity, unitPrice: changedUnitPrice || undefined }); + + return manager.findOne(MaterialsInventoryEntity, { where: { id } }); } /** @@ -407,14 +447,22 @@ export class MaterialsInventoryService { data: { quantity: number; inventoryId?: number; + productId: number; + unitPrice?: number; }, manager: EntityManager - ): Promise { - const { quantity: outQuantity, inventoryId } = data; - + ): Promise { + const { quantity: outQuantity, inventoryId, productId, unitPrice } = data; + let searchPayload: any = {}; + if (inventoryId) { + searchPayload.id = inventoryId; + } else { + // 删除出入库记录时,需要根据产品ID和价格查找库存 + searchPayload = { productId, unitPrice }; + } // 开启悲观行锁,防止脏读和修改 const inventory = await manager.findOne(MaterialsInventoryEntity, { - where: { id: inventoryId }, + where: searchPayload, lock: { mode: 'pessimistic_write' } }); // 检查库存剩余 @@ -430,6 +478,8 @@ export class MaterialsInventoryService { await manager.update(MaterialsInventoryEntity, id, { quantity: newQuantity }); + + return manager.findOne(MaterialsInventoryEntity, { where: { id } }); } /** @@ -467,4 +517,31 @@ export class MaterialsInventoryService { .getOne(); return info; } + + /** + * 生成库存编号 + * @returns 库存编号 + */ + async generateInventoryNumber() { + const prefix = + ( + await this.paramConfigRepository.findOne({ + where: { + key: ParamConfigEnum.InventoryNumberPrefix + } + }) + )?.value || ''; + const lastInventory = await this.materialsInventoryRepository + .createQueryBuilder('materials_inventory') + .select( + `MAX(CAST(REPLACE(materials_inventory.inventoryNumber, '${prefix}', '') AS UNSIGNED))`, + 'maxInventoryNumber' + ) + .getRawOne(); + const lastNumber = lastInventory.maxInventoryNumber + ? parseInt(lastInventory.maxInventoryNumber.replace(prefix, '')) + : 0; + const newNumber = lastNumber + 1 < 1000 ? 1000 : lastNumber + 1; + return `${prefix}${newNumber}`; + } } diff --git a/src/modules/product/product.entity.ts b/src/modules/product/product.entity.ts index 6fbbce5..f7bfad6 100644 --- a/src/modules/product/product.entity.ts +++ b/src/modules/product/product.entity.ts @@ -17,7 +17,6 @@ import pinyin from 'pinyin'; import { DictItemEntity } from '../system/dict-item/dict-item.entity'; @Entity({ name: 'product' }) export class ProductEntity extends CommonEntity { - @Column({ name: 'product_number', type: 'varchar', @@ -35,7 +34,7 @@ export class ProductEntity extends CommonEntity { }) @ApiProperty({ description: '产品名称' }) name: string; - + @Column({ name: 'product_specification', type: 'varchar', @@ -45,6 +44,7 @@ export class ProductEntity extends CommonEntity { }) @ApiProperty({ description: '产品规格', nullable: true }) productSpecification?: string; + @Column({ name: 'remark', type: 'varchar',