feat: project filter

This commit is contained in:
louis 2024-03-29 14:41:54 +08:00
parent 59b77cdbc5
commit 072777b5e5
4 changed files with 102 additions and 94 deletions

View File

@ -9,7 +9,7 @@ export class LoginDto {
@ApiProperty({ description: '密码', example: 'a123456' })
@IsString()
@Matches(/^\S*(?=\S{6,})(?=\S*\d)(?=\S*[A-Za-z])\S*$/)
@Matches(/^\S*(?=\S{6,})(?=\S*\d)(?=\S*[A-Za-z])\S*$/, { message: '密码错误' })
@MinLength(6)
password: string;

View File

@ -103,7 +103,7 @@ export class MaterialsInOutService {
position,
unitPrice,
quantity,
productId
productId
} = dto;
inventoryInOutNumber = await this.generateInventoryInOutNumber(inOrOut);
let newRecordId;
@ -130,84 +130,85 @@ export class MaterialsInOutService {
*/
async update(id: number, { fileIds, ...data }: Partial<MaterialsInOutUpdateDto>): Promise<void> {
await this.entityManager.transaction(async manager => {
const entity = await manager.findOne(MaterialsInOutEntity, {
where: {
id
},
lock: { mode: 'pessimistic_write' }
});
/* 暂时不允许更改金额和数量,以及不能影响库存变化, */
// const entity = await manager.findOne(MaterialsInOutEntity, {
// where: {
// id
// },
// lock: { mode: 'pessimistic_write' }
// });
//
// 修改入库记录的价格,会直接更改库存实际价格.
// 1.如果有了出库记录,不允许修改入库价格。
if (
Object.is(data.inOrOut, MaterialsInOrOutEnum.In) &&
isDefined(data.unitPrice) &&
Math.abs(Number(data.unitPrice) - Number(entity.unitPrice)) !== 0
) {
const outEntity = await manager.findOne(MaterialsInOutEntity, {
where: {
unitPrice: entity.unitPrice,
inOrOut: MaterialsInOrOutEnum.Out,
projectId: entity.projectId,
productId: entity.productId
}
});
if (isDefined(outEntity)) {
throw new BusinessException(ErrorEnum.MATERIALS_IN_OUT_UNIT_PRICE_CANNOT_BE_MODIFIED);
}
await (
Object.is(data.inOrOut, MaterialsInOrOutEnum.In)
? this.materialsInventoryService.inInventory.bind(this.materialsInventoryService)
: this.materialsInventoryService.outInventory.bind(this.materialsInventoryService)
)(
{
productId: entity.productId,
quantity: 0,
unitPrice: entity.unitPrice,
projectId: entity.projectId,
changedUnitPrice: data.unitPrice
},
manager
);
}
// if (
// Object.is(data.inOrOut, MaterialsInOrOutEnum.In) &&
// isDefined(data.unitPrice) &&
// Math.abs(Number(data.unitPrice) - Number(entity.unitPrice)) !== 0
// ) {
// const outEntity = await manager.findOne(MaterialsInOutEntity, {
// where: {
// unitPrice: entity.unitPrice,
// inOrOut: MaterialsInOrOutEnum.Out,
// projectId: entity.projectId,
// productId: entity.productId
// }
// });
// if (isDefined(outEntity)) {
// throw new BusinessException(ErrorEnum.MATERIALS_IN_OUT_UNIT_PRICE_CANNOT_BE_MODIFIED);
// }
// await (
// Object.is(data.inOrOut, MaterialsInOrOutEnum.In)
// ? this.materialsInventoryService.inInventory.bind(this.materialsInventoryService)
// : this.materialsInventoryService.outInventory.bind(this.materialsInventoryService)
// )(
// {
// productId: entity.productId,
// quantity: 0,
// unitPrice: entity.unitPrice,
// projectId: entity.projectId,
// changedUnitPrice: data.unitPrice
// },
// manager
// );
// }
let changedQuantity = 0;
if (isDefined(data.quantity) && entity.quantity !== data.quantity) {
if (entity.inOrOut === MaterialsInOrOutEnum.In) {
// 入库减少等于出库
if (data.quantity - entity.quantity < 0) {
data.inOrOut = MaterialsInOrOutEnum.Out;
} else {
// 入库增多等于入库
data.inOrOut = MaterialsInOrOutEnum.In;
}
} else {
// 出库减少等于入库
if (data.quantity - entity.quantity < 0) {
data.inOrOut = MaterialsInOrOutEnum.In;
} else {
// 出库增多等于出库
data.inOrOut = MaterialsInOrOutEnum.Out;
}
}
changedQuantity = Math.abs(data.quantity - entity.quantity);
}
// 2.更新增减库存
if (changedQuantity !== 0) {
await (
Object.is(data.inOrOut, MaterialsInOrOutEnum.In)
? this.materialsInventoryService.inInventory
: this.materialsInventoryService.outInventory
)(
{
productId: entity.productId,
quantity: Math.abs(changedQuantity),
unitPrice: undefined,
projectId: entity.projectId
},
manager
);
}
// let changedQuantity = 0;
// if (isDefined(data.quantity) && entity.quantity !== data.quantity) {
// if (entity.inOrOut === MaterialsInOrOutEnum.In) {
// // 入库减少等于出库
// if (data.quantity - entity.quantity < 0) {
// data.inOrOut = MaterialsInOrOutEnum.Out;
// } else {
// // 入库增多等于入库
// data.inOrOut = MaterialsInOrOutEnum.In;
// }
// } else {
// // 出库减少等于入库
// if (data.quantity - entity.quantity < 0) {
// data.inOrOut = MaterialsInOrOutEnum.In;
// } else {
// // 出库增多等于出库
// data.inOrOut = MaterialsInOrOutEnum.Out;
// }
// }
// changedQuantity = Math.abs(data.quantity - entity.quantity);
// }
// // 2.更新增减库存
// if (changedQuantity !== 0) {
// await (
// Object.is(data.inOrOut, MaterialsInOrOutEnum.In)
// ? this.materialsInventoryService.inInventory
// : this.materialsInventoryService.outInventory
// )(
// {
// productId: entity.productId,
// quantity: Math.abs(changedQuantity),
// unitPrice: undefined,
// projectId: entity.projectId
// },
// manager
// );
// }
// 完成所有业务逻辑后,更新出入库记录
await manager.update(MaterialsInOutEntity, id, {
...data
@ -254,10 +255,8 @@ export class MaterialsInOutService {
: this.materialsInventoryService.inInventory.bind(this.materialsInventoryService)
)(
{
productId: entity.productId,
quantity: entity.quantity,
unitPrice: entity.unitPrice,
projectId: entity.projectId
inventoryId: entity.inventoryId
},
manager
);

View File

@ -40,6 +40,11 @@ export class MaterialsInventoryQueryDto extends IntersectionType(
@IsOptional()
@IsEnum(HasInventoryStatusEnum)
isHasInventory: HasInventoryStatusEnum;
@ApiProperty({ description: '项目Id' })
@IsOptional()
@IsNumber()
projectId: number;
}
export class MaterialsInventoryExportDto {
@ApiProperty({ description: '项目' })

View File

@ -318,6 +318,7 @@ export class MaterialsInventoryService {
pageSize,
product,
keyword,
projectId,
isHasInventory
}: MaterialsInventoryQueryDto): Promise<Pagination<MaterialsInventoryEntity>> {
const queryBuilder = this.materialsInventoryRepository
@ -342,6 +343,11 @@ export class MaterialsInventoryService {
if (product) {
queryBuilder.andWhere('product.name like :product', { product: `%${product}%` });
}
if (projectId) {
queryBuilder.andWhere('project.id = :projectId', { projectId });
}
if (keyword) {
queryBuilder.andWhere(
'(materialsInventory.inventoryNumber like :keyword or product.name like :keyword or product.productNumber like :keyword or product.productSpecification like :keyword)',
@ -392,6 +398,7 @@ export class MaterialsInventoryService {
projectId: number;
productId: number;
quantity: number;
inventoryId?: number;
unitPrice?: number;
changedUnitPrice?: number;
},
@ -403,11 +410,17 @@ export class MaterialsInventoryService {
quantity: inQuantity,
unitPrice,
changedUnitPrice,
position
position,
inventoryId
} = data;
let searchPayload: any = {};
if (isDefined(inventoryId)) {
searchPayload = { id: inventoryId };
} else {
searchPayload = { projectId, productId, unitPrice };
}
const exsitedInventory = await manager.findOne(MaterialsInventoryEntity, {
where: { projectId, productId, unitPrice }, // 根据项目,产品,价格查出之前的实时库存情况
where: searchPayload, // 根据项目,产品,价格查出之前的实时库存情况
lock: { mode: 'pessimistic_write' } // 开启悲观行锁,防止脏读和修改
});
@ -447,22 +460,13 @@ export class MaterialsInventoryService {
data: {
quantity: number;
inventoryId?: number;
productId: number;
unitPrice?: number;
},
manager: EntityManager
): Promise<MaterialsInventoryEntity> {
const { quantity: outQuantity, inventoryId, productId, unitPrice } = data;
let searchPayload: any = {};
if (inventoryId) {
searchPayload.id = inventoryId;
} else {
// 删除出入库记录时需要根据产品ID和价格查找库存
searchPayload = { productId, unitPrice };
}
const { quantity: outQuantity, inventoryId } = data;
// 开启悲观行锁,防止脏读和修改
const inventory = await manager.findOne(MaterialsInventoryEntity, {
where: searchPayload,
where: { id: inventoryId },
lock: { mode: 'pessimistic_write' }
});
// 检查库存剩余