feat: sale_quotation
This commit is contained in:
parent
b4dc00ecd4
commit
c815e5d561
|
@ -30,6 +30,7 @@ import { CompanyModule } from './modules/company/company.module';
|
||||||
import { ProductModule } from './modules/product/product.module';
|
import { ProductModule } from './modules/product/product.module';
|
||||||
import { ProjectModule } from './modules/project/project.module';
|
import { ProjectModule } from './modules/project/project.module';
|
||||||
import { VehicleUsageModule } from './modules/vehicle_usage/vehicle_usage.module';
|
import { VehicleUsageModule } from './modules/vehicle_usage/vehicle_usage.module';
|
||||||
|
import { SaleQuotationModule } from './modules/sale_quotation/sale_quotation.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -73,7 +74,10 @@ import { VehicleUsageModule } from './modules/vehicle_usage/vehicle_usage.module
|
||||||
ProjectModule,
|
ProjectModule,
|
||||||
|
|
||||||
// 车辆管理
|
// 车辆管理
|
||||||
VehicleUsageModule
|
VehicleUsageModule,
|
||||||
|
|
||||||
|
//报价管理
|
||||||
|
SaleQuotationModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: APP_FILTER, useClass: AllExceptionsFilter },
|
{ provide: APP_FILTER, useClass: AllExceptionsFilter },
|
||||||
|
|
|
@ -61,5 +61,8 @@ export enum ErrorEnum {
|
||||||
INVENTORY_INSUFFICIENT = '1408:库存数量不足。请检查库存或重新操作',
|
INVENTORY_INSUFFICIENT = '1408:库存数量不足。请检查库存或重新操作',
|
||||||
MATERIALS_IN_OUT_NOT_FOUND = '1409:出入库信息不存在',
|
MATERIALS_IN_OUT_NOT_FOUND = '1409:出入库信息不存在',
|
||||||
MATERIALS_IN_OUT_UNIT_PRICE_CANNOT_BE_MODIFIED = '1410:该价格的产品已经出库,单价不允许修改。若有疑问,请联系管理员',
|
MATERIALS_IN_OUT_UNIT_PRICE_CANNOT_BE_MODIFIED = '1410:该价格的产品已经出库,单价不允许修改。若有疑问,请联系管理员',
|
||||||
MATERIALS_IN_OUT_UNIT_PRICE_MUST_ZERO_WHEN_MODIFIED = '1411:只能修改初始单价为0的入库记录。 若有疑问,请联系管理员'
|
MATERIALS_IN_OUT_UNIT_PRICE_MUST_ZERO_WHEN_MODIFIED = '1411:只能修改初始单价为0的入库记录。 若有疑问,请联系管理员',
|
||||||
|
|
||||||
|
// SaleQuotation
|
||||||
|
SALE_QUOTATION_COMPONENT_DUPLICATED = '1412:存在名称,价格,规格都相同的配件,请检查是否重复录入'
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,11 +56,6 @@ export class ProjectService {
|
||||||
await manager.update(ProjectEntity, id, {
|
await manager.update(ProjectEntity, id, {
|
||||||
...data
|
...data
|
||||||
});
|
});
|
||||||
const project = await this.projectRepository
|
|
||||||
.createQueryBuilder('project')
|
|
||||||
.leftJoinAndSelect('project.files', 'files')
|
|
||||||
.where('project.id = :id', { id })
|
|
||||||
.getOne();
|
|
||||||
if (fileIds?.length) {
|
if (fileIds?.length) {
|
||||||
const count = await this.storageRepository
|
const count = await this.storageRepository
|
||||||
.createQueryBuilder('storage')
|
.createQueryBuilder('storage')
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { Body, Controller, Get, Query, Put, Delete, Post } from '@nestjs/common';
|
||||||
|
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator';
|
||||||
|
import { ApiResult } from '~/common/decorators/api-result.decorator';
|
||||||
|
import { IdParam } from '~/common/decorators/id-param.decorator';
|
||||||
|
import { Perm, definePermission } from '~/modules/auth/decorators/permission.decorator';
|
||||||
|
import { SaleQuotationComponentDto, SaleQuotationComponentQueryDto, SaleQuotationComponentUpdateDto } from './sale_quotation_component.dto';
|
||||||
|
import { SaleQuotationComponentService } from './sale_quotation_component.service';
|
||||||
|
export const permissions = definePermission('sale_quotation:sale_quotation_component', {
|
||||||
|
LIST: 'list',
|
||||||
|
CREATE: 'create',
|
||||||
|
READ: 'read',
|
||||||
|
UPDATE: 'update',
|
||||||
|
DELETE: 'delete'
|
||||||
|
} as const);
|
||||||
|
|
||||||
|
@ApiTags('SaleQuotationComponent - 报价配件')
|
||||||
|
@ApiSecurityAuth()
|
||||||
|
@Controller('sale_quotation_component')
|
||||||
|
export class SaleQuotationComponentController {
|
||||||
|
constructor(private saleQuotationComponentService: SaleQuotationComponentService) {}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@ApiOperation({ summary: '分页获取报价配件列表' })
|
||||||
|
@ApiResult({ type: [SaleQuotationComponentDto], isPage: true })
|
||||||
|
@Perm(permissions.LIST)
|
||||||
|
async list(@Query() dto: SaleQuotationComponentQueryDto) {
|
||||||
|
return this.saleQuotationComponentService.findAll(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
@ApiOperation({ summary: '获取报价配件信息' })
|
||||||
|
@ApiResult({ type: SaleQuotationComponentDto })
|
||||||
|
@Perm(permissions.READ)
|
||||||
|
async info(@IdParam() id: number) {
|
||||||
|
return this.saleQuotationComponentService.info(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
@ApiOperation({ summary: '新增报价配件' })
|
||||||
|
@Perm(permissions.CREATE)
|
||||||
|
async create(@Body() dto: SaleQuotationComponentDto): Promise<void> {
|
||||||
|
await this.saleQuotationComponentService.create(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put(':id')
|
||||||
|
@ApiOperation({ summary: '更新报价配件' })
|
||||||
|
@Perm(permissions.UPDATE)
|
||||||
|
async update(@IdParam() id: number, @Body() dto: SaleQuotationComponentUpdateDto): Promise<void> {
|
||||||
|
await this.saleQuotationComponentService.update(id, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(':id')
|
||||||
|
@ApiOperation({ summary: '删除报价配件' })
|
||||||
|
@Perm(permissions.DELETE)
|
||||||
|
async delete(@IdParam() id: number): Promise<void> {
|
||||||
|
await this.saleQuotationComponentService.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('unlink-attachments/:id')
|
||||||
|
@ApiOperation({ summary: '附件解除关联' })
|
||||||
|
@Perm(permissions.UPDATE)
|
||||||
|
async unlinkAttachments(
|
||||||
|
@IdParam() id: number,
|
||||||
|
@Body() { fileIds }: SaleQuotationComponentUpdateDto
|
||||||
|
): Promise<void> {
|
||||||
|
await this.saleQuotationComponentService.unlinkAttachments(id, fileIds);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { ApiProperty, IntersectionType, PartialType } from '@nestjs/swagger';
|
||||||
|
import { IsArray, IsNumber, IsOptional, IsString } from 'class-validator';
|
||||||
|
import { PagerDto } from '~/common/dto/pager.dto';
|
||||||
|
import { Storage } from '~/modules/tools/storage/storage.entity';
|
||||||
|
import { IsUnique } from '~/shared/database/constraints/unique.constraint';
|
||||||
|
import { SaleQuotationComponentEntity } from './sale_quotation_component.entity';
|
||||||
|
|
||||||
|
export class SaleQuotationComponentDto {
|
||||||
|
@ApiProperty({ description: '报价配件名称' })
|
||||||
|
@IsString()
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: '配件规格' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
componentSpecification: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: '配件备注' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
remark: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: '单位(字典)' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
unitId: number;
|
||||||
|
|
||||||
|
@ApiProperty({ description: '单价' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
unitPrice: number;
|
||||||
|
|
||||||
|
@ApiProperty({ description: '附件' })
|
||||||
|
files: Storage[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SaleQuotationComponentUpdateDto extends PartialType(SaleQuotationComponentDto) {
|
||||||
|
@ApiProperty({ description: '附件' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsArray()
|
||||||
|
fileIds: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ComapnyCreateDto extends PartialType(SaleQuotationComponentDto) {
|
||||||
|
@ApiProperty({ description: '附件' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsArray()
|
||||||
|
fileIds: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SaleQuotationComponentQueryDto extends IntersectionType(
|
||||||
|
PagerDto<SaleQuotationComponentDto>,
|
||||||
|
PartialType(SaleQuotationComponentDto)
|
||||||
|
) {
|
||||||
|
@ApiProperty({ description: '报价配件名称' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
name: string;
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
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 { Storage } from '~/modules/tools/storage/storage.entity';
|
||||||
|
import { SaleQuotationGroupEntity } from '../group/sale_quotation_group.entity';
|
||||||
|
import { DictItemEntity } from '~/modules/system/dict-item/dict-item.entity';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报价配件实体类
|
||||||
|
*/
|
||||||
|
@Entity({ name: 'sale_quotation_component' })
|
||||||
|
export class SaleQuotationComponentEntity extends CommonEntity {
|
||||||
|
@Column({
|
||||||
|
name: 'name',
|
||||||
|
type: 'varchar',
|
||||||
|
length: 255,
|
||||||
|
comment: '报价配件名称'
|
||||||
|
})
|
||||||
|
@ApiProperty({ description: '报价配件名称' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'component_specification',
|
||||||
|
type: 'varchar',
|
||||||
|
nullable: true,
|
||||||
|
length: 255,
|
||||||
|
comment: '产品规格'
|
||||||
|
})
|
||||||
|
@ApiProperty({ description: '产品规格', nullable: true })
|
||||||
|
componentSpecification?: string;
|
||||||
|
|
||||||
|
@Column({ name: 'unit_id', type: 'int', comment: '单位(字典)', nullable: true })
|
||||||
|
@ApiProperty({ description: '单位(字典)' })
|
||||||
|
unitId: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => DictItemEntity)
|
||||||
|
@JoinColumn({ name: 'unit_id' })
|
||||||
|
unit: DictItemEntity;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'unit_price',
|
||||||
|
type: 'decimal',
|
||||||
|
precision: 15,
|
||||||
|
default: 0,
|
||||||
|
scale: 10,
|
||||||
|
comment: '单价'
|
||||||
|
})
|
||||||
|
@ApiProperty({ description: '单价' })
|
||||||
|
unitPrice: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'remark',
|
||||||
|
type: 'varchar',
|
||||||
|
length: 255,
|
||||||
|
nullable: true,
|
||||||
|
comment: '备注'
|
||||||
|
})
|
||||||
|
@ApiProperty({ description: '产品备注' })
|
||||||
|
remark: string;
|
||||||
|
|
||||||
|
@Column({ name: 'is_delete', type: 'tinyint', default: 0, comment: '是否删除' })
|
||||||
|
@ApiProperty({ description: '删除状态:0未删除,1已删除' })
|
||||||
|
isDelete: number;
|
||||||
|
|
||||||
|
@ManyToMany(() => Storage, storage => storage.saleQuotationComponents)
|
||||||
|
@JoinTable({
|
||||||
|
name: 'sale_quotation_component_storage',
|
||||||
|
joinColumn: { name: 'sale_quotation_component_id', referencedColumnName: 'id' },
|
||||||
|
inverseJoinColumn: { name: 'file_id', referencedColumnName: 'id' }
|
||||||
|
})
|
||||||
|
files: Relation<Storage[]>;
|
||||||
|
|
||||||
|
@ApiHideProperty()
|
||||||
|
@ManyToMany(() => SaleQuotationGroupEntity, group => group.components)
|
||||||
|
groups: Relation<SaleQuotationGroupEntity[]>;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { StorageModule } from '~/modules/tools/storage/storage.module';
|
||||||
|
import { DatabaseModule } from '~/shared/database/database.module';
|
||||||
|
import { SaleQuotationComponentService } from './sale_quotation_component.service';
|
||||||
|
import { SaleQuotationComponentController } from './sale_quotation_component.controller';
|
||||||
|
import { SaleQuotationComponentEntity } from './sale_quotation_component.entity';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [TypeOrmModule.forFeature([SaleQuotationComponentEntity]), StorageModule, DatabaseModule],
|
||||||
|
controllers: [SaleQuotationComponentController],
|
||||||
|
providers: [SaleQuotationComponentService]
|
||||||
|
})
|
||||||
|
export class SaleQuotationComponentModule {}
|
|
@ -0,0 +1,161 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { EntityManager, Not, Repository } from 'typeorm';
|
||||||
|
import { Pagination } from '~/helper/paginate/pagination';
|
||||||
|
import { paginate } from '~/helper/paginate';
|
||||||
|
import { BusinessException } from '~/common/exceptions/biz.exception';
|
||||||
|
import { ErrorEnum } from '~/constants/error-code.constant';
|
||||||
|
import { fieldSearch } from '~/shared/database/field-search';
|
||||||
|
import { SaleQuotationComponentEntity } from './sale_quotation_component.entity';
|
||||||
|
import { Storage } from '~/modules/tools/storage/storage.entity';
|
||||||
|
import {
|
||||||
|
SaleQuotationComponentDto,
|
||||||
|
SaleQuotationComponentQueryDto,
|
||||||
|
SaleQuotationComponentUpdateDto
|
||||||
|
} from './sale_quotation_component.dto';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SaleQuotationComponentService {
|
||||||
|
constructor(
|
||||||
|
@InjectEntityManager() private entityManager: EntityManager,
|
||||||
|
@InjectRepository(SaleQuotationComponentEntity)
|
||||||
|
private saleQuotationComponentRepository: Repository<SaleQuotationComponentEntity>,
|
||||||
|
@InjectRepository(Storage)
|
||||||
|
private storageRepository: Repository<Storage>
|
||||||
|
) {}
|
||||||
|
|
||||||
|
buildSearchQuery() {
|
||||||
|
return this.saleQuotationComponentRepository
|
||||||
|
.createQueryBuilder('saleQuotationComponent')
|
||||||
|
.leftJoin('saleQuotationComponent.unit', 'unit')
|
||||||
|
.leftJoin('saleQuotationComponent.files', 'files')
|
||||||
|
.addSelect(['files.id', 'files.path', 'unit.id', 'unit.label']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询所有
|
||||||
|
*/
|
||||||
|
async findAll({
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
...fields
|
||||||
|
}: SaleQuotationComponentQueryDto): Promise<Pagination<SaleQuotationComponentEntity>> {
|
||||||
|
const queryBuilder = this.buildSearchQuery()
|
||||||
|
.where(fieldSearch(fields))
|
||||||
|
.andWhere('saleQuotationComponent.isDelete = 0');
|
||||||
|
|
||||||
|
return paginate<SaleQuotationComponentEntity>(queryBuilder, {
|
||||||
|
page,
|
||||||
|
pageSize
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增
|
||||||
|
*/
|
||||||
|
async create(dto: SaleQuotationComponentDto): Promise<void> {
|
||||||
|
const { unitPrice, name, componentSpecification } = dto;
|
||||||
|
const isExist = await this.saleQuotationComponentRepository.exist({
|
||||||
|
where: {
|
||||||
|
unitPrice,
|
||||||
|
name,
|
||||||
|
componentSpecification
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (isExist) {
|
||||||
|
throw new BusinessException(ErrorEnum.SALE_QUOTATION_COMPONENT_DUPLICATED);
|
||||||
|
}
|
||||||
|
await this.saleQuotationComponentRepository.insert(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新
|
||||||
|
*/
|
||||||
|
async update(
|
||||||
|
id: number,
|
||||||
|
{ fileIds, ...data }: Partial<SaleQuotationComponentUpdateDto>
|
||||||
|
): Promise<void> {
|
||||||
|
await this.entityManager.transaction(async manager => {
|
||||||
|
const beUpdateEntity = await manager.findOne(SaleQuotationComponentEntity, {
|
||||||
|
where: {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const { unitPrice, name, componentSpecification } = beUpdateEntity;
|
||||||
|
const isExist = await this.saleQuotationComponentRepository.exist({
|
||||||
|
where: {
|
||||||
|
id: Not(id),
|
||||||
|
unitPrice,
|
||||||
|
name,
|
||||||
|
componentSpecification
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (isExist) {
|
||||||
|
throw new BusinessException(ErrorEnum.SALE_QUOTATION_COMPONENT_DUPLICATED);
|
||||||
|
}
|
||||||
|
await manager.update(SaleQuotationComponentEntity, id, {
|
||||||
|
...data
|
||||||
|
});
|
||||||
|
if (fileIds?.length) {
|
||||||
|
const count = await this.storageRepository
|
||||||
|
.createQueryBuilder('storage')
|
||||||
|
.where('storage.id in(:fileIds)', { fileIds })
|
||||||
|
.getCount();
|
||||||
|
if (count !== fileIds?.length) {
|
||||||
|
throw new BusinessException(ErrorEnum.STORAGE_NOT_FOUND);
|
||||||
|
}
|
||||||
|
// 附件要批量插入
|
||||||
|
await manager
|
||||||
|
.createQueryBuilder()
|
||||||
|
.relation(SaleQuotationComponentEntity, 'files')
|
||||||
|
.of(id)
|
||||||
|
.add(fileIds);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
*/
|
||||||
|
async delete(id: number): Promise<void> {
|
||||||
|
// 比较重要,做逻辑删除
|
||||||
|
await this.saleQuotationComponentRepository.update(id, { isDelete: 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个信息
|
||||||
|
*/
|
||||||
|
async info(id: number) {
|
||||||
|
const info = await this.buildSearchQuery()
|
||||||
|
.where({
|
||||||
|
id
|
||||||
|
})
|
||||||
|
.andWhere('saleQuotationComponent.isDelete = 0')
|
||||||
|
.getOne();
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解除附件关联
|
||||||
|
* @param id 实体ID
|
||||||
|
* @param fileIds 附件ID
|
||||||
|
*/
|
||||||
|
async unlinkAttachments(id: number, fileIds: number[]) {
|
||||||
|
await this.entityManager.transaction(async manager => {
|
||||||
|
const saleQuotationComponent = await this.saleQuotationComponentRepository
|
||||||
|
.createQueryBuilder('saleQuotationComponent')
|
||||||
|
.leftJoinAndSelect('saleQuotationComponent.files', 'files')
|
||||||
|
.where('saleQuotationComponent.id = :id', { id })
|
||||||
|
.getOne();
|
||||||
|
const linkedFiles = saleQuotationComponent.files
|
||||||
|
.map(item => item.id)
|
||||||
|
.filter(item => !fileIds.includes(item));
|
||||||
|
// 附件要批量更新
|
||||||
|
await manager
|
||||||
|
.createQueryBuilder()
|
||||||
|
.relation(SaleQuotationComponentEntity, 'files')
|
||||||
|
.of(id)
|
||||||
|
.addAndRemove(linkedFiles, saleQuotationComponent.files);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
import { Body, Controller, Get, Query, Put, Delete, Post } from '@nestjs/common';
|
||||||
|
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator';
|
||||||
|
import { ApiResult } from '~/common/decorators/api-result.decorator';
|
||||||
|
import { IdParam } from '~/common/decorators/id-param.decorator';
|
||||||
|
import { Perm, definePermission } from '~/modules/auth/decorators/permission.decorator';
|
||||||
|
import {
|
||||||
|
SaleQuotationGroupDto,
|
||||||
|
SaleQuotationGroupQueryDto,
|
||||||
|
SaleQuotationGroupUpdateDto
|
||||||
|
} from './sale_quotation_group.dto';
|
||||||
|
import { SaleQuotationGroupService } from './sale_quotation_group.service';
|
||||||
|
export const permissions = definePermission('sale_quotation:sale_quotation_group', {
|
||||||
|
LIST: 'list',
|
||||||
|
CREATE: 'create',
|
||||||
|
READ: 'read',
|
||||||
|
UPDATE: 'update',
|
||||||
|
DELETE: 'delete'
|
||||||
|
} as const);
|
||||||
|
|
||||||
|
@ApiTags('SaleQuotationGroup - 报价分组')
|
||||||
|
@ApiSecurityAuth()
|
||||||
|
@Controller('sale_quotation_group')
|
||||||
|
export class SaleQuotationGroupController {
|
||||||
|
constructor(private saleQuotationGroupService: SaleQuotationGroupService) {}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@ApiOperation({ summary: '分页获取报价分组列表' })
|
||||||
|
@ApiResult({ type: [SaleQuotationGroupDto], isPage: true })
|
||||||
|
@Perm(permissions.LIST)
|
||||||
|
async list(@Query() dto: SaleQuotationGroupQueryDto) {
|
||||||
|
return this.saleQuotationGroupService.findAll(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
@ApiOperation({ summary: '获取报价分组信息' })
|
||||||
|
@ApiResult({ type: SaleQuotationGroupDto })
|
||||||
|
@Perm(permissions.READ)
|
||||||
|
async info(@IdParam() id: number) {
|
||||||
|
return this.saleQuotationGroupService.info(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
@ApiOperation({ summary: '新增报价分组' })
|
||||||
|
@Perm(permissions.CREATE)
|
||||||
|
async create(@Body() dto: SaleQuotationGroupDto): Promise<void> {
|
||||||
|
await this.saleQuotationGroupService.create(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put(':id')
|
||||||
|
@ApiOperation({ summary: '更新报价分组' })
|
||||||
|
@Perm(permissions.UPDATE)
|
||||||
|
async update(@IdParam() id: number, @Body() dto: SaleQuotationGroupUpdateDto): Promise<void> {
|
||||||
|
await this.saleQuotationGroupService.update(id, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(':id')
|
||||||
|
@ApiOperation({ summary: '删除报价分组' })
|
||||||
|
@Perm(permissions.DELETE)
|
||||||
|
async delete(@IdParam() id: number): Promise<void> {
|
||||||
|
await this.saleQuotationGroupService.delete(id);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { ApiProperty, IntersectionType, PartialType } from '@nestjs/swagger';
|
||||||
|
import { IsArray, IsNumber, IsOptional, IsString } from 'class-validator';
|
||||||
|
import { PagerDto } from '~/common/dto/pager.dto';
|
||||||
|
import { Storage } from '~/modules/tools/storage/storage.entity';
|
||||||
|
import { IsUnique } from '~/shared/database/constraints/unique.constraint';
|
||||||
|
import { SaleQuotationGroupEntity } from './sale_quotation_group.entity';
|
||||||
|
|
||||||
|
export class SaleQuotationGroupDto {
|
||||||
|
@ApiProperty({ description: '报价分组名称' })
|
||||||
|
@IsUnique(SaleQuotationGroupEntity, { message: '已存在同名报价分组' })
|
||||||
|
@IsString()
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SaleQuotationGroupUpdateDto extends PartialType(SaleQuotationGroupDto) {}
|
||||||
|
|
||||||
|
export class ComapnyCreateDto extends PartialType(SaleQuotationGroupDto) {}
|
||||||
|
|
||||||
|
export class SaleQuotationGroupQueryDto extends IntersectionType(
|
||||||
|
PagerDto<SaleQuotationGroupDto>,
|
||||||
|
PartialType(SaleQuotationGroupDto)
|
||||||
|
) {
|
||||||
|
@ApiProperty({ description: '报价分组名称' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
name: string;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
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 { Storage } from '~/modules/tools/storage/storage.entity';
|
||||||
|
import { SaleQuotationComponentEntity } from '../component/sale_quotation_component.entity';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报价分组实体类
|
||||||
|
*/
|
||||||
|
@Entity({ name: 'sale_quotation_group' })
|
||||||
|
export class SaleQuotationGroupEntity extends CommonEntity {
|
||||||
|
@Column({
|
||||||
|
name: 'name',
|
||||||
|
type: 'varchar',
|
||||||
|
unique: true,
|
||||||
|
length: 255,
|
||||||
|
comment: '报价分组名称'
|
||||||
|
})
|
||||||
|
@ApiProperty({ description: '报价分组名称' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({ name: 'is_delete', type: 'tinyint', default: 0, comment: '是否删除' })
|
||||||
|
@ApiProperty({ description: '删除状态:0未删除,1已删除' })
|
||||||
|
isDelete: number;
|
||||||
|
|
||||||
|
@ManyToMany(() => SaleQuotationComponentEntity, component => component.groups)
|
||||||
|
@JoinTable({
|
||||||
|
name: 'sale_quotation_group_component',
|
||||||
|
joinColumn: { name: 'group_id', referencedColumnName: 'id' },
|
||||||
|
inverseJoinColumn: { name: 'component_id', referencedColumnName: 'id' }
|
||||||
|
})
|
||||||
|
components: Relation<SaleQuotationComponentEntity[]>;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { StorageModule } from '~/modules/tools/storage/storage.module';
|
||||||
|
import { DatabaseModule } from '~/shared/database/database.module';
|
||||||
|
import { SaleQuotationGroupService } from './sale_quotation_group.service';
|
||||||
|
import { SaleQuotationGroupController } from './sale_quotation_group.controller';
|
||||||
|
import { SaleQuotationGroupEntity } from './sale_quotation_group.entity';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [TypeOrmModule.forFeature([SaleQuotationGroupEntity]), DatabaseModule],
|
||||||
|
controllers: [SaleQuotationGroupController],
|
||||||
|
providers: [SaleQuotationGroupService]
|
||||||
|
})
|
||||||
|
export class SaleQuotationGroupModule {}
|
|
@ -0,0 +1,83 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { EntityManager, Repository } from 'typeorm';
|
||||||
|
import { Pagination } from '~/helper/paginate/pagination';
|
||||||
|
import { paginate } from '~/helper/paginate';
|
||||||
|
import { BusinessException } from '~/common/exceptions/biz.exception';
|
||||||
|
import { ErrorEnum } from '~/constants/error-code.constant';
|
||||||
|
import { fieldSearch } from '~/shared/database/field-search';
|
||||||
|
import { SaleQuotationGroupEntity } from './sale_quotation_group.entity';
|
||||||
|
import { Storage } from '~/modules/tools/storage/storage.entity';
|
||||||
|
import {
|
||||||
|
SaleQuotationGroupDto,
|
||||||
|
SaleQuotationGroupQueryDto,
|
||||||
|
SaleQuotationGroupUpdateDto
|
||||||
|
} from './sale_quotation_group.dto';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SaleQuotationGroupService {
|
||||||
|
constructor(
|
||||||
|
@InjectEntityManager() private entityManager: EntityManager,
|
||||||
|
@InjectRepository(SaleQuotationGroupEntity)
|
||||||
|
private saleQuotationGroupRepository: Repository<SaleQuotationGroupEntity>
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询所有
|
||||||
|
*/
|
||||||
|
async findAll({
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
...fields
|
||||||
|
}: SaleQuotationGroupQueryDto): Promise<Pagination<SaleQuotationGroupEntity>> {
|
||||||
|
const queryBuilder = this.saleQuotationGroupRepository
|
||||||
|
.createQueryBuilder('saleQuotationGroup')
|
||||||
|
.where(fieldSearch(fields))
|
||||||
|
.andWhere('saleQuotationGroup.isDelete = 0');
|
||||||
|
|
||||||
|
return paginate<SaleQuotationGroupEntity>(queryBuilder, {
|
||||||
|
page,
|
||||||
|
pageSize
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增
|
||||||
|
*/
|
||||||
|
async create(dto: SaleQuotationGroupDto): Promise<void> {
|
||||||
|
await this.saleQuotationGroupRepository.insert(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新
|
||||||
|
*/
|
||||||
|
async update(id: number, data: Partial<SaleQuotationGroupUpdateDto>): Promise<void> {
|
||||||
|
await this.entityManager.transaction(async manager => {
|
||||||
|
await manager.update(SaleQuotationGroupEntity, id, {
|
||||||
|
...data
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
*/
|
||||||
|
async delete(id: number): Promise<void> {
|
||||||
|
// 比较重要,做逻辑删除
|
||||||
|
await this.saleQuotationGroupRepository.update(id, { isDelete: 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个信息
|
||||||
|
*/
|
||||||
|
async info(id: number) {
|
||||||
|
const info = await this.saleQuotationGroupRepository
|
||||||
|
.createQueryBuilder('saleQuotationGroup')
|
||||||
|
.where({
|
||||||
|
id
|
||||||
|
})
|
||||||
|
.andWhere('saleQuotationGroup.isDelete = 0')
|
||||||
|
.getOne();
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { SaleQuotationGroupModule } from './group/sale_quotation_group.module';
|
||||||
|
import { SaleQuotationTemplateModule } from './template/sale_quotation_template.module';
|
||||||
|
import { SaleQuotationComponentModule } from './component/sale_quotation_component.module';
|
||||||
|
import { RouterModule } from '@nestjs/core';
|
||||||
|
const modules = [
|
||||||
|
SaleQuotationComponentModule,
|
||||||
|
SaleQuotationGroupModule,
|
||||||
|
SaleQuotationTemplateModule
|
||||||
|
];
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
...modules,
|
||||||
|
RouterModule.register([
|
||||||
|
{
|
||||||
|
path: 'sale_quotation',
|
||||||
|
module: SaleQuotationModule,
|
||||||
|
children: [...modules]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
],
|
||||||
|
controllers: [],
|
||||||
|
providers: []
|
||||||
|
})
|
||||||
|
export class SaleQuotationModule {}
|
|
@ -0,0 +1,63 @@
|
||||||
|
import { Body, Controller, Get, Query, Put, Delete, Post } from '@nestjs/common';
|
||||||
|
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator';
|
||||||
|
import { ApiResult } from '~/common/decorators/api-result.decorator';
|
||||||
|
import { IdParam } from '~/common/decorators/id-param.decorator';
|
||||||
|
import { Perm, definePermission } from '~/modules/auth/decorators/permission.decorator';
|
||||||
|
import {
|
||||||
|
SaleQuotationTemplateDto,
|
||||||
|
SaleQuotationTemplateQueryDto,
|
||||||
|
SaleQuotationTemplateUpdateDto
|
||||||
|
} from './sale_quotation_template.dto';
|
||||||
|
import { SaleQuotationTemplateService } from './sale_quotation_template.service';
|
||||||
|
export const permissions = definePermission('sale_quotation:sale_quotation_template', {
|
||||||
|
LIST: 'list',
|
||||||
|
CREATE: 'create',
|
||||||
|
READ: 'read',
|
||||||
|
UPDATE: 'update',
|
||||||
|
DELETE: 'delete'
|
||||||
|
} as const);
|
||||||
|
|
||||||
|
@ApiTags('SaleQuotationTemplate - 报价模板')
|
||||||
|
@ApiSecurityAuth()
|
||||||
|
@Controller('sale_quotation_template')
|
||||||
|
export class SaleQuotationTemplateController {
|
||||||
|
constructor(private saleQuotationTemplateService: SaleQuotationTemplateService) {}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@ApiOperation({ summary: '分页获取报价模板列表' })
|
||||||
|
@ApiResult({ type: [SaleQuotationTemplateDto], isPage: true })
|
||||||
|
@Perm(permissions.LIST)
|
||||||
|
async list(@Query() dto: SaleQuotationTemplateQueryDto) {
|
||||||
|
return this.saleQuotationTemplateService.findAll(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
@ApiOperation({ summary: '获取报价模板信息' })
|
||||||
|
@ApiResult({ type: SaleQuotationTemplateDto })
|
||||||
|
@Perm(permissions.READ)
|
||||||
|
async info(@IdParam() id: number) {
|
||||||
|
return this.saleQuotationTemplateService.info(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
@ApiOperation({ summary: '新增报价模板' })
|
||||||
|
@Perm(permissions.CREATE)
|
||||||
|
async create(@Body() dto: SaleQuotationTemplateDto): Promise<void> {
|
||||||
|
await this.saleQuotationTemplateService.create(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put(':id')
|
||||||
|
@ApiOperation({ summary: '更新报价模板' })
|
||||||
|
@Perm(permissions.UPDATE)
|
||||||
|
async update(@IdParam() id: number, @Body() dto: SaleQuotationTemplateUpdateDto): Promise<void> {
|
||||||
|
await this.saleQuotationTemplateService.update(id, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(':id')
|
||||||
|
@ApiOperation({ summary: '删除报价模板' })
|
||||||
|
@Perm(permissions.DELETE)
|
||||||
|
async delete(@IdParam() id: number): Promise<void> {
|
||||||
|
await this.saleQuotationTemplateService.delete(id);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { ApiProperty, IntersectionType, PartialType } from '@nestjs/swagger';
|
||||||
|
import { IsOptional, IsString } from 'class-validator';
|
||||||
|
import { PagerDto } from '~/common/dto/pager.dto';
|
||||||
|
import { IsUnique } from '~/shared/database/constraints/unique.constraint';
|
||||||
|
import { SaleQuotationTemplateEntity } from './sale_quotation_template.entity';
|
||||||
|
|
||||||
|
export class SaleQuotationTemplateDto {
|
||||||
|
@ApiProperty({ description: '报价模板名称' })
|
||||||
|
@IsString()
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: '报价模板' })
|
||||||
|
@IsOptional()
|
||||||
|
template: JSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SaleQuotationTemplateUpdateDto extends PartialType(SaleQuotationTemplateDto) {}
|
||||||
|
|
||||||
|
export class ComapnyCreateDto extends PartialType(SaleQuotationTemplateDto) {}
|
||||||
|
|
||||||
|
export class SaleQuotationTemplateQueryDto extends IntersectionType(
|
||||||
|
PagerDto<SaleQuotationTemplateDto>,
|
||||||
|
PartialType(SaleQuotationTemplateDto)
|
||||||
|
) {
|
||||||
|
@ApiProperty({ description: '报价模板名称' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
name: string;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { Column, Entity } from 'typeorm';
|
||||||
|
import { CommonEntity } from '~/common/entity/common.entity';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报价模板实体类
|
||||||
|
*/
|
||||||
|
@Entity({ name: 'sale_quotation_template' })
|
||||||
|
export class SaleQuotationTemplateEntity extends CommonEntity {
|
||||||
|
@Column({
|
||||||
|
name: 'name',
|
||||||
|
type: 'varchar',
|
||||||
|
unique: true,
|
||||||
|
length: 255,
|
||||||
|
comment: '报价模板名称'
|
||||||
|
})
|
||||||
|
@ApiProperty({ description: '报价模板名称' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'template',
|
||||||
|
type: 'json',
|
||||||
|
comment: '报价模板',
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
@ApiProperty({ description: '报价模板(JSON)' })
|
||||||
|
template: JSON;
|
||||||
|
|
||||||
|
@Column({ name: 'is_delete', type: 'tinyint', default: 0, comment: '是否删除' })
|
||||||
|
@ApiProperty({ description: '删除状态:0未删除,1已删除' })
|
||||||
|
isDelete: number;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { StorageModule } from '~/modules/tools/storage/storage.module';
|
||||||
|
import { DatabaseModule } from '~/shared/database/database.module';
|
||||||
|
import { SaleQuotationTemplateService } from './sale_quotation_template.service';
|
||||||
|
import { SaleQuotationTemplateController } from './sale_quotation_template.controller';
|
||||||
|
import { SaleQuotationTemplateEntity } from './sale_quotation_template.entity';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [TypeOrmModule.forFeature([SaleQuotationTemplateEntity]), DatabaseModule],
|
||||||
|
controllers: [SaleQuotationTemplateController],
|
||||||
|
providers: [SaleQuotationTemplateService]
|
||||||
|
})
|
||||||
|
export class SaleQuotationTemplateModule {}
|
|
@ -0,0 +1,83 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { EntityManager, Repository } from 'typeorm';
|
||||||
|
import { Pagination } from '~/helper/paginate/pagination';
|
||||||
|
import { paginate } from '~/helper/paginate';
|
||||||
|
import { BusinessException } from '~/common/exceptions/biz.exception';
|
||||||
|
import { ErrorEnum } from '~/constants/error-code.constant';
|
||||||
|
import { fieldSearch } from '~/shared/database/field-search';
|
||||||
|
import { SaleQuotationTemplateEntity } from './sale_quotation_template.entity';
|
||||||
|
import { Storage } from '~/modules/tools/storage/storage.entity';
|
||||||
|
import {
|
||||||
|
SaleQuotationTemplateDto,
|
||||||
|
SaleQuotationTemplateQueryDto,
|
||||||
|
SaleQuotationTemplateUpdateDto
|
||||||
|
} from './sale_quotation_template.dto';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SaleQuotationTemplateService {
|
||||||
|
constructor(
|
||||||
|
@InjectEntityManager() private entityManager: EntityManager,
|
||||||
|
@InjectRepository(SaleQuotationTemplateEntity)
|
||||||
|
private saleQuotationTemplateRepository: Repository<SaleQuotationTemplateEntity>
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询所有
|
||||||
|
*/
|
||||||
|
async findAll({
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
...fields
|
||||||
|
}: SaleQuotationTemplateQueryDto): Promise<Pagination<SaleQuotationTemplateEntity>> {
|
||||||
|
const queryBuilder = this.saleQuotationTemplateRepository
|
||||||
|
.createQueryBuilder('saleQuotationTemplate')
|
||||||
|
.where(fieldSearch(fields))
|
||||||
|
.andWhere('saleQuotationTemplate.isDelete = 0').addOrderBy('saleQuotationTemplate.createdAt', 'DESC');
|
||||||
|
|
||||||
|
return paginate<SaleQuotationTemplateEntity>(queryBuilder, {
|
||||||
|
page,
|
||||||
|
pageSize
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增
|
||||||
|
*/
|
||||||
|
async create(dto: SaleQuotationTemplateDto): Promise<void> {
|
||||||
|
await this.saleQuotationTemplateRepository.insert(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新
|
||||||
|
*/
|
||||||
|
async update(id: number, data: Partial<SaleQuotationTemplateUpdateDto>): Promise<void> {
|
||||||
|
await this.entityManager.transaction(async manager => {
|
||||||
|
await manager.update(SaleQuotationTemplateEntity, id, {
|
||||||
|
...data
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
*/
|
||||||
|
async delete(id: number): Promise<void> {
|
||||||
|
// 比较重要,做逻辑删除
|
||||||
|
await this.saleQuotationTemplateRepository.update(id, { isDelete: 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个信息
|
||||||
|
*/
|
||||||
|
async info(id: number) {
|
||||||
|
const info = await this.saleQuotationTemplateRepository
|
||||||
|
.createQueryBuilder('saleQuotationTemplate')
|
||||||
|
.where({
|
||||||
|
id
|
||||||
|
})
|
||||||
|
.andWhere('saleQuotationTemplate.isDelete = 0')
|
||||||
|
.getOne();
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ import { MaterialsInOutEntity } from '~/modules/materials_inventory/in_out/mater
|
||||||
import { MaterialsInventoryEntity } from '~/modules/materials_inventory/materials_inventory.entity';
|
import { MaterialsInventoryEntity } from '~/modules/materials_inventory/materials_inventory.entity';
|
||||||
import { ProductEntity } from '~/modules/product/product.entity';
|
import { ProductEntity } from '~/modules/product/product.entity';
|
||||||
import { ProjectEntity } from '~/modules/project/project.entity';
|
import { ProjectEntity } from '~/modules/project/project.entity';
|
||||||
|
import { SaleQuotationComponentEntity } from '~/modules/sale_quotation/component/sale_quotation_component.entity';
|
||||||
import { VehicleUsageEntity } from '~/modules/vehicle_usage/vehicle_usage.entity';
|
import { VehicleUsageEntity } from '~/modules/vehicle_usage/vehicle_usage.entity';
|
||||||
|
|
||||||
@Entity({ name: 'tool_storage' })
|
@Entity({ name: 'tool_storage' })
|
||||||
|
@ -77,4 +78,9 @@ export class Storage extends CommonEntity {
|
||||||
@ApiHideProperty()
|
@ApiHideProperty()
|
||||||
@ManyToMany(() => VehicleUsageEntity, vu => vu.files)
|
@ManyToMany(() => VehicleUsageEntity, vu => vu.files)
|
||||||
vehicleUsage: Relation<VehicleUsageEntity[]>;
|
vehicleUsage: Relation<VehicleUsageEntity[]>;
|
||||||
|
|
||||||
|
@ApiHideProperty()
|
||||||
|
@ManyToMany(() => SaleQuotationComponentEntity, component => component.files)
|
||||||
|
saleQuotationComponents: Relation<SaleQuotationComponentEntity[]>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue