feat: 出入库记录模块完善
This commit is contained in:
parent
cf7c91eab2
commit
466c3ca384
|
@ -18,3 +18,8 @@ export enum MaterialsInOrOutEnum {
|
|||
In,
|
||||
Out
|
||||
}
|
||||
|
||||
// 系统参数key
|
||||
export enum ParamConfigEnum {
|
||||
MaterialsInOutPrefix = 'materials_in_out_prefix'
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { ApiProperty, IntersectionType, PartialType } from '@nestjs/swagger';
|
|||
import { Transform } from 'class-transformer';
|
||||
import {
|
||||
IsArray,
|
||||
IsBoolean,
|
||||
IsDate,
|
||||
IsDateString,
|
||||
IsEnum,
|
||||
|
@ -11,7 +12,8 @@ import {
|
|||
IsOptional,
|
||||
IsString,
|
||||
Matches,
|
||||
MinLength
|
||||
MinLength,
|
||||
ValidateIf
|
||||
} from 'class-validator';
|
||||
import dayjs from 'dayjs';
|
||||
import { PagerDto } from '~/common/dto/pager.dto';
|
||||
|
@ -21,9 +23,15 @@ import { formatToDate } from '~/utils';
|
|||
|
||||
export class MaterialsInOutDto {
|
||||
@ApiProperty({ description: '产品' })
|
||||
@ValidateIf(o => !o.inventoryNumber)
|
||||
@IsNumber()
|
||||
productId: number;
|
||||
|
||||
@ApiProperty({ description: '原材料库存编号' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
inventoryNumber: string;
|
||||
|
||||
@ApiProperty({ description: '单位(字典)' })
|
||||
@IsNumber()
|
||||
@IsOptional()
|
||||
|
@ -68,10 +76,6 @@ export class MaterialsInOutDto {
|
|||
@IsString()
|
||||
@ApiProperty({ description: '项目' })
|
||||
project: string;
|
||||
|
||||
// @ApiProperty({ description: '附件' })
|
||||
// @IsOptional()
|
||||
// files: Storage[];
|
||||
}
|
||||
|
||||
export class MaterialsInOutUpdateDto extends PartialType(MaterialsInOutDto) {
|
||||
|
@ -80,7 +84,7 @@ export class MaterialsInOutUpdateDto extends PartialType(MaterialsInOutDto) {
|
|||
@IsArray()
|
||||
fileIds: number[];
|
||||
}
|
||||
export class MaterialsInOutQueryDto extends PagerDto<MaterialsInOutDto> {
|
||||
export class MaterialsInOutQueryDto extends PagerDto<MaterialsInOutQueryDto> {
|
||||
@ApiProperty({ description: '出入库时间YYYY-MM-DD' })
|
||||
@IsOptional()
|
||||
// @IsString()
|
||||
|
@ -97,10 +101,41 @@ export class MaterialsInOutQueryDto extends PagerDto<MaterialsInOutDto> {
|
|||
@ApiProperty({ description: '入库或出库 0:入库 1:出库' })
|
||||
@IsOptional()
|
||||
@IsEnum(MaterialsInOrOutEnum)
|
||||
inOrOut: MaterialsInOrOutEnum;
|
||||
inOrOut?: MaterialsInOrOutEnum;
|
||||
|
||||
@ApiProperty({ description: '产品名称' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
product: string;
|
||||
product?: string;
|
||||
|
||||
@ApiProperty({ description: '经办人' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
agent?: string;
|
||||
|
||||
@ApiProperty({ description: '领料单号' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
issuanceNumber?: string;
|
||||
|
||||
@ApiProperty({ description: '原材料库存编号' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
inventoryNumber?: string;
|
||||
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@ApiProperty({ description: '备注' })
|
||||
remark?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@ApiProperty({ description: '项目' })
|
||||
project?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
@ApiProperty({ description: '是否是用于创建出库记录' })
|
||||
isCreateOut?: boolean;
|
||||
}
|
||||
|
|
|
@ -1,23 +1,34 @@
|
|||
import { ApiHideProperty, ApiProperty } from '@nestjs/swagger';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Expose } from 'class-transformer';
|
||||
import pinyin from 'pinyin';
|
||||
import {
|
||||
BeforeInsert,
|
||||
Column,
|
||||
Entity,
|
||||
JoinColumn,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
ManyToOne,
|
||||
OneToMany,
|
||||
Relation,
|
||||
VirtualColumn
|
||||
Repository
|
||||
} from 'typeorm';
|
||||
import { CommonEntity } from '~/common/entity/common.entity';
|
||||
import { MaterialsInOrOutEnum } from '~/constants/enum';
|
||||
import { MaterialsInOrOutEnum, ParamConfigEnum } from '~/constants/enum';
|
||||
import { ProductEntity } from '~/modules/product/product.entity';
|
||||
import { DictItemEntity } from '~/modules/system/dict-item/dict-item.entity';
|
||||
import { ParamConfigEntity } from '~/modules/system/param-config/param-config.entity';
|
||||
import { Storage } from '~/modules/tools/storage/storage.entity';
|
||||
|
||||
@Entity({ name: 'materials_in_out' })
|
||||
export class MaterialsInOutEntity extends CommonEntity {
|
||||
@Column({
|
||||
name: 'inventory_number',
|
||||
type: 'varchar',
|
||||
length: 50,
|
||||
comment: '原材料库存编号'
|
||||
})
|
||||
@ApiProperty({ description: '原材料库存编号' })
|
||||
inventoryNumber: string;
|
||||
|
||||
@Column({
|
||||
name: 'product_id',
|
||||
type: 'int',
|
||||
|
@ -55,9 +66,9 @@ export class MaterialsInOutEntity extends CommonEntity {
|
|||
@Column({
|
||||
name: 'unit_price',
|
||||
type: 'decimal',
|
||||
precision: 10,
|
||||
precision: 15,
|
||||
default: 0,
|
||||
scale: 2,
|
||||
scale: 10,
|
||||
comment: '单价'
|
||||
})
|
||||
@ApiProperty({ description: '单价' })
|
||||
|
@ -66,9 +77,9 @@ export class MaterialsInOutEntity extends CommonEntity {
|
|||
@Column({
|
||||
name: 'amount',
|
||||
type: 'decimal',
|
||||
precision: 10,
|
||||
precision: 15,
|
||||
default: 0,
|
||||
scale: 2,
|
||||
scale: 10,
|
||||
comment: '金额'
|
||||
})
|
||||
@ApiProperty({ description: '金额' })
|
||||
|
@ -104,9 +115,6 @@ export class MaterialsInOutEntity extends CommonEntity {
|
|||
@JoinColumn({ name: 'product_id' })
|
||||
product: ProductEntity;
|
||||
|
||||
@ApiHideProperty()
|
||||
unit: DictItemEntity;
|
||||
|
||||
@ManyToMany(() => Storage, storage => storage.materialsInOut)
|
||||
@JoinTable({
|
||||
name: 'materials_in_out_storage',
|
||||
|
|
|
@ -14,6 +14,8 @@ import {
|
|||
} from './materials_in_out.dto';
|
||||
import { MaterialsInOutEntity } from './materials_in_out.entity';
|
||||
import { fieldSearch } from '~/shared/database/field-search';
|
||||
import { ParamConfigEntity } from '~/modules/system/param-config/param-config.entity';
|
||||
import { MaterialsInOrOutEnum, ParamConfigEnum } from '~/constants/enum';
|
||||
|
||||
@Injectable()
|
||||
export class MaterialsInOutService {
|
||||
|
@ -22,7 +24,9 @@ export class MaterialsInOutService {
|
|||
@InjectRepository(MaterialsInOutEntity)
|
||||
private materialsInOutRepository: Repository<MaterialsInOutEntity>,
|
||||
@InjectRepository(Storage)
|
||||
private storageRepository: Repository<Storage>
|
||||
private storageRepository: Repository<Storage>,
|
||||
@InjectRepository(ParamConfigEntity)
|
||||
private paramConfigRepository: Repository<ParamConfigEntity>
|
||||
) {}
|
||||
/**
|
||||
* 查询所有出入库记录
|
||||
|
@ -31,6 +35,7 @@ export class MaterialsInOutService {
|
|||
page,
|
||||
pageSize,
|
||||
product: productName,
|
||||
isCreateOut,
|
||||
...ext
|
||||
}: MaterialsInOutQueryDto): Promise<Pagination<MaterialsInOutEntity>> {
|
||||
const sqb = this.materialsInOutRepository
|
||||
|
@ -38,23 +43,21 @@ export class MaterialsInOutService {
|
|||
.leftJoin('materialsInOut.files', 'files')
|
||||
.leftJoin('materialsInOut.product', 'product')
|
||||
.leftJoin('product.unit', 'unit')
|
||||
.addSelect(['files.id', 'files.path', 'product.id', 'product.name', 'unit.id', 'unit.label'])
|
||||
.leftJoin('product.company', 'company')
|
||||
.addSelect(['files.path', 'product.name', 'unit.label', 'company.name'])
|
||||
.where(fieldSearch(ext))
|
||||
.andWhere('materialsInOut.isDelete = 0')
|
||||
.addOrderBy('materialsInOut.time', 'DESC');
|
||||
.addOrderBy('materialsInOut.createdAt', 'DESC');
|
||||
if (productName) {
|
||||
sqb.andWhere('product.name like :productName', { productName: `%${productName}%` });
|
||||
}
|
||||
let pageData = await paginate<MaterialsInOutEntity>(sqb, {
|
||||
if (isCreateOut) {
|
||||
sqb.andWhere('materialsInOut.inOrOut = 0');
|
||||
}
|
||||
const pageData = await paginate<MaterialsInOutEntity>(sqb, {
|
||||
page,
|
||||
pageSize
|
||||
});
|
||||
// 产品表中的单位字段需要单独处理
|
||||
pageData.items = pageData.items.map(materialsInOut => {
|
||||
materialsInOut.unit = materialsInOut.product.unit;
|
||||
delete materialsInOut.product.unit;
|
||||
return materialsInOut;
|
||||
});
|
||||
return pageData;
|
||||
}
|
||||
|
||||
|
@ -62,7 +65,22 @@ export class MaterialsInOutService {
|
|||
* 新增
|
||||
*/
|
||||
async create(dto: MaterialsInOutDto): Promise<void> {
|
||||
await this.materialsInOutRepository.insert(dto);
|
||||
let { inOrOut, inventoryNumber } = dto;
|
||||
if (inOrOut === MaterialsInOrOutEnum.In) {
|
||||
inventoryNumber = await this.generateInventoryNumber();
|
||||
} else {
|
||||
const inRecord = await this.materialsInOutRepository.findOne({
|
||||
where: {
|
||||
inventoryNumber
|
||||
}
|
||||
});
|
||||
const { productId } = inRecord;
|
||||
dto.productId = productId;
|
||||
}
|
||||
await this.materialsInOutRepository.insert({
|
||||
...this.materialsInOutRepository.create(dto),
|
||||
inventoryNumber
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,4 +159,31 @@ export class MaterialsInOutService {
|
|||
.addAndRemove(linkedFiles, materialsInOut.files);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成库存单号
|
||||
* @returns 库存单号
|
||||
*/
|
||||
async generateInventoryNumber() {
|
||||
const prefix =
|
||||
(
|
||||
await this.paramConfigRepository.findOne({
|
||||
where: {
|
||||
key: ParamConfigEnum.MaterialsInOutPrefix
|
||||
}
|
||||
})
|
||||
)?.value || '';
|
||||
const lastMaterial = await this.materialsInOutRepository
|
||||
.createQueryBuilder('materialsInOut')
|
||||
.select(
|
||||
`MAX(CAST(REPLACE(materialsInOut.inventoryNumber, '${prefix}', '') AS UNSIGNED))`,
|
||||
'maxInventoryNumber'
|
||||
)
|
||||
.getRawOne();
|
||||
const lastNumber = lastMaterial.maxInventoryNumber
|
||||
? parseInt(lastMaterial.maxInventoryNumber.replace(prefix, ''))
|
||||
: 0;
|
||||
const newNumber = lastNumber + 1 < 1000 ? 1000 : lastNumber + 1;
|
||||
return `${prefix}${newNumber}`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,12 @@ import { StorageModule } from '../tools/storage/storage.module';
|
|||
import { MaterialsInOutController } from './in_out/materials_in_out.controller';
|
||||
import { MaterialsInOutService } from './in_out/materials_in_out.service';
|
||||
import { MaterialsInOutEntity } from './in_out/materials_in_out.entity';
|
||||
import { ParamConfigModule } from '../system/param-config/param-config.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([MaterialsInventoryEntity, MaterialsInOutEntity]),
|
||||
ParamConfigModule,
|
||||
StorageModule
|
||||
],
|
||||
controllers: [MaterialsInventoryController, MaterialsInOutController],
|
||||
|
|
Loading…
Reference in New Issue