This commit is contained in:
+20
-3
@@ -88,14 +88,31 @@ export class DocumentNumberingController {
|
||||
})
|
||||
@RequirePermission('correspondence.read')
|
||||
async previewNumber(@Body() dto: PreviewNumberDto) {
|
||||
// ADR-019: Resolve UUID→INT for project and organization IDs
|
||||
const resolvedProjectId = await this.numberingService.resolveIdForPreview(
|
||||
'project',
|
||||
dto.projectId
|
||||
);
|
||||
const resolvedOriginatorId =
|
||||
await this.numberingService.resolveIdForPreview(
|
||||
'organization',
|
||||
dto.originatorOrganizationId
|
||||
);
|
||||
const resolvedRecipientId = dto.recipientOrganizationId
|
||||
? await this.numberingService.resolveIdForPreview(
|
||||
'organization',
|
||||
dto.recipientOrganizationId
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return this.numberingService.previewNumber({
|
||||
projectId: dto.projectId,
|
||||
originatorOrganizationId: dto.originatorOrganizationId,
|
||||
projectId: resolvedProjectId,
|
||||
originatorOrganizationId: resolvedOriginatorId,
|
||||
typeId: dto.correspondenceTypeId,
|
||||
subTypeId: dto.subTypeId,
|
||||
rfaTypeId: dto.rfaTypeId,
|
||||
disciplineId: dto.disciplineId,
|
||||
recipientOrganizationId: dto.recipientOrganizationId,
|
||||
recipientOrganizationId: resolvedRecipientId,
|
||||
year: dto.year,
|
||||
customTokens: dto.customTokens,
|
||||
});
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
// File: src/modules/document-numbering/dto/preview-number.dto.ts
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
import { IsInt, IsOptional, IsObject } from 'class-validator';
|
||||
import { IsInt, IsNotEmpty, IsOptional, IsObject } from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
|
||||
export class PreviewNumberDto {
|
||||
@ApiProperty({ description: 'Project ID' })
|
||||
@IsInt()
|
||||
@Type(() => Number)
|
||||
projectId!: number;
|
||||
@ApiProperty({ description: 'Project ID or UUID' })
|
||||
@IsNotEmpty()
|
||||
projectId!: number | string;
|
||||
|
||||
@ApiProperty({ description: 'Originator organization ID' })
|
||||
@IsInt()
|
||||
@Type(() => Number)
|
||||
originatorOrganizationId!: number;
|
||||
@ApiProperty({ description: 'Originator organization ID or UUID' })
|
||||
@IsNotEmpty()
|
||||
originatorOrganizationId!: number | string;
|
||||
|
||||
@ApiProperty({ description: 'Correspondence type ID' })
|
||||
@IsInt()
|
||||
@@ -43,11 +41,9 @@ export class PreviewNumberDto {
|
||||
@Type(() => Number)
|
||||
year?: number;
|
||||
|
||||
@ApiPropertyOptional({ description: 'Recipient organization ID' })
|
||||
@ApiPropertyOptional({ description: 'Recipient organization ID or UUID' })
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
@Type(() => Number)
|
||||
recipientOrganizationId?: number;
|
||||
recipientOrganizationId?: number | string;
|
||||
|
||||
@ApiPropertyOptional({ description: 'Custom tokens' })
|
||||
@IsOptional()
|
||||
|
||||
@@ -26,6 +26,7 @@ import { GenerateNumberContext } from '../interfaces/document-numbering.interfac
|
||||
import { ReserveNumberDto } from '../dto/reserve-number.dto';
|
||||
import { ConfirmReservationDto } from '../dto/confirm-reservation.dto';
|
||||
import { Project } from '../../project/entities/project.entity';
|
||||
import { Organization } from '../../organization/entities/organization.entity';
|
||||
|
||||
@Injectable()
|
||||
export class DocumentNumberingService {
|
||||
@@ -66,6 +67,33 @@ export class DocumentNumberingService {
|
||||
return project.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* ADR-019: Public facade for controllers to resolve project/organization IDs
|
||||
*/
|
||||
async resolveIdForPreview(
|
||||
type: 'project' | 'organization',
|
||||
id: number | string
|
||||
): Promise<number> {
|
||||
if (type === 'project') return this.resolveProjectId(id);
|
||||
return this.resolveOrganizationId(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* ADR-019: Resolve organizationId (INT or UUID string) to internal INT ID
|
||||
*/
|
||||
private async resolveOrganizationId(orgId: number | string): Promise<number> {
|
||||
if (typeof orgId === 'number') return orgId;
|
||||
const num = Number(orgId);
|
||||
if (!isNaN(num)) return num;
|
||||
const org = await this.entityManager.findOne(Organization, {
|
||||
where: { uuid: orgId },
|
||||
select: ['id'],
|
||||
});
|
||||
if (!org)
|
||||
throw new NotFoundException(`Organization with UUID ${orgId} not found`);
|
||||
return org.id;
|
||||
}
|
||||
|
||||
async generateNextNumber(
|
||||
ctx: GenerateNumberContext
|
||||
): Promise<{ number: string; auditId: number }> {
|
||||
|
||||
Reference in New Issue
Block a user