690503:1547 Update #01
CI / CD Pipeline / build (push) Successful in 5m13s
CI / CD Pipeline / deploy (push) Successful in 4m18s

This commit is contained in:
2026-05-03 15:47:59 +07:00
parent 912b25bd06
commit 42a6d24318
10 changed files with 452 additions and 354 deletions
@@ -111,4 +111,17 @@ export class CirculationController {
) {
return this.circulationService.forceClose(uuid, dto.reason, user);
}
@Post(':uuid/close')
@HttpCode(HttpStatus.OK)
@ApiOperation({
summary:
'Close a Circulation when all Main/Action routings are completed (FR-C09)',
})
@ApiParam({ name: 'uuid', description: 'Circulation publicId' })
@RequirePermission('circulation.manage')
@Audit('circulation.close', 'circulation')
close(@Param('uuid', ParseUuidPipe) uuid: string, @CurrentUser() user: User) {
return this.circulationService.close(uuid, user);
}
}
@@ -299,6 +299,47 @@ export class CirculationService {
}
}
/**
* EC-CIRC-00X: Close Circulation (FR-C09)
* ต้องมีสิทธิ์ circulation.close (หรือ circulation.manage) เช็คใน controller
*/
async close(publicId: string, user: User) {
const circulation = await this.circulationRepo.findOne({
where: { publicId },
relations: ['routings'],
});
if (!circulation)
throw new NotFoundException(`Circulation publicId ${publicId}`);
if (
circulation.statusCode === 'COMPLETED' ||
circulation.statusCode === 'CANCELLED' ||
circulation.statusCode === 'CLOSED'
) {
throw new ValidationException(
`ใบเวียน ${circulation.circulationNo} ปิดไปแล้ว (${circulation.statusCode})`
);
}
const pendingCount = circulation.routings.filter(
(r) => r.status === 'PENDING' || r.status === 'IN_PROGRESS'
).length;
if (pendingCount > 0) {
throw new ValidationException(
'All Main/Action routings must be COMPLETED before closing'
);
}
circulation.statusCode = 'CLOSED';
circulation.closedAt = new Date();
await this.circulationRepo.save(circulation);
this.logger.log(`Circulation ${publicId} closed by user ${user.user_id}`);
return { success: true };
}
// ✅ Logic อัปเดตสถานะและปิดงาน
async updateRoutingStatus(
routingId: number,