251215:1719 Docunment Number Rule not correct
This commit is contained in:
@@ -1,15 +1,34 @@
|
||||
import apiClient from '@/lib/api/client';
|
||||
|
||||
// Types
|
||||
export interface NumberingTemplate {
|
||||
templateId: number;
|
||||
projectId?: number;
|
||||
documentTypeId?: string;
|
||||
documentTypeName: string;
|
||||
disciplineCode?: string;
|
||||
templateFormat: string;
|
||||
exampleNumber: string;
|
||||
currentNumber: number;
|
||||
resetAnnually: boolean;
|
||||
id?: number; // Backend uses 'id'
|
||||
templateId?: number; // Legacy, optional
|
||||
projectId: number;
|
||||
correspondenceTypeId: number;
|
||||
correspondenceType?: { typeCode: string; typeName: string }; // Relation
|
||||
documentTypeName?: string; // Optional (joined)
|
||||
disciplineId: number;
|
||||
discipline?: { disciplineCode: string; disciplineName: string }; // Relation
|
||||
disciplineCode?: string; // Optional (joined)
|
||||
formatTemplate: string; // Backend uses 'formatTemplate'
|
||||
templateFormat?: string; // Legacy alias
|
||||
exampleNumber?: string;
|
||||
paddingLength: number;
|
||||
resetAnnually: boolean;
|
||||
isActive: boolean;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface NumberingTemplateDto {
|
||||
projectId: number;
|
||||
correspondenceTypeId: number;
|
||||
disciplineId?: number; // 0 = All
|
||||
formatTemplate: string;
|
||||
exampleNumber?: string;
|
||||
paddingLength: number;
|
||||
resetAnnually: boolean;
|
||||
isActive: boolean;
|
||||
}
|
||||
|
||||
@@ -23,138 +42,82 @@ export interface NumberSequence {
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
// Mock Data
|
||||
const mockTemplates: NumberingTemplate[] = [
|
||||
{
|
||||
templateId: 1,
|
||||
projectId: 1,
|
||||
documentTypeName: 'Correspondence',
|
||||
disciplineCode: '',
|
||||
templateFormat: '{ORIGINATOR}-{RECIPIENT}-{SEQ:4}-{YEAR:B.E.}',
|
||||
exampleNumber: 'PAT-CN-0001-2568',
|
||||
currentNumber: 142,
|
||||
resetAnnually: true,
|
||||
paddingLength: 4,
|
||||
isActive: true,
|
||||
},
|
||||
{
|
||||
templateId: 2,
|
||||
projectId: 1,
|
||||
documentTypeName: 'RFA',
|
||||
disciplineCode: 'STR',
|
||||
templateFormat: '{PROJECT}-{CORR_TYPE}-{DISCIPLINE}-{RFA_TYPE}-{SEQ:4}-{REV}',
|
||||
exampleNumber: 'LCBP3-RFA-STR-SDW-0056-A',
|
||||
currentNumber: 56,
|
||||
resetAnnually: true,
|
||||
paddingLength: 4,
|
||||
isActive: true,
|
||||
},
|
||||
{
|
||||
templateId: 3,
|
||||
projectId: 2,
|
||||
documentTypeName: 'Maintenance Request',
|
||||
disciplineCode: '',
|
||||
templateFormat: 'MAINT-{SEQ:4}',
|
||||
exampleNumber: 'MAINT-0001',
|
||||
currentNumber: 1,
|
||||
resetAnnually: true,
|
||||
paddingLength: 4,
|
||||
isActive: true,
|
||||
},
|
||||
];
|
||||
|
||||
const mockSequences: NumberSequence[] = [
|
||||
{
|
||||
sequenceId: 1,
|
||||
year: 2025,
|
||||
organizationCode: 'PAT',
|
||||
currentNumber: 142,
|
||||
lastGeneratedNumber: 'PAT-CORR-2025-0142',
|
||||
updatedAt: new Date().toISOString(),
|
||||
},
|
||||
{
|
||||
sequenceId: 2,
|
||||
year: 2025,
|
||||
disciplineCode: 'STR',
|
||||
currentNumber: 56,
|
||||
lastGeneratedNumber: 'RFA-STR-2025-0056',
|
||||
updatedAt: new Date().toISOString(),
|
||||
},
|
||||
];
|
||||
|
||||
export const numberingApi = {
|
||||
getTemplates: async (): Promise<NumberingTemplate[]> => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => resolve([...mockTemplates]), 500);
|
||||
});
|
||||
const res = await apiClient.get<NumberingTemplate[]>('/admin/document-numbering/templates');
|
||||
return res.data.map(t => ({
|
||||
...t,
|
||||
templateId: t.id,
|
||||
templateFormat: t.formatTemplate,
|
||||
// Map joined data if available, else placeholders
|
||||
documentTypeName: t.correspondenceType?.typeCode || 'UNKNOWN',
|
||||
disciplineCode: t.discipline?.disciplineCode || 'ALL',
|
||||
}));
|
||||
},
|
||||
|
||||
getTemplate: async (id: number): Promise<NumberingTemplate | undefined> => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => resolve(mockTemplates.find(t => t.templateId === id)), 300);
|
||||
});
|
||||
// Currently no single get endpoint
|
||||
const templates = await numberingApi.getTemplates();
|
||||
return templates.find(t => t.id === id);
|
||||
},
|
||||
|
||||
saveTemplate: async (template: Partial<NumberingTemplate>): Promise<NumberingTemplate> => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
if (template.templateId) {
|
||||
// Update
|
||||
const index = mockTemplates.findIndex(t => t.templateId === template.templateId);
|
||||
if (index !== -1) {
|
||||
mockTemplates[index] = { ...mockTemplates[index], ...template } as NumberingTemplate;
|
||||
resolve(mockTemplates[index]);
|
||||
}
|
||||
} else {
|
||||
// Create
|
||||
const newTemplate: NumberingTemplate = {
|
||||
templateId: Math.floor(Math.random() * 1000),
|
||||
documentTypeName: 'New Type',
|
||||
isActive: true,
|
||||
currentNumber: 0,
|
||||
exampleNumber: 'PREVIEW',
|
||||
templateFormat: template.templateFormat || '',
|
||||
disciplineCode: template.disciplineCode,
|
||||
paddingLength: template.paddingLength ?? 4,
|
||||
resetAnnually: template.resetAnnually ?? true,
|
||||
...template
|
||||
} as NumberingTemplate;
|
||||
mockTemplates.push(newTemplate);
|
||||
resolve(newTemplate);
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
// Map frontend interface to backend entity DTO
|
||||
const payload = {
|
||||
id: template.id || template.templateId, // Update if ID exists
|
||||
projectId: template.projectId,
|
||||
correspondenceTypeId: template.correspondenceTypeId,
|
||||
disciplineId: template.disciplineId || 0,
|
||||
formatTemplate: template.templateFormat || template.formatTemplate,
|
||||
exampleNumber: template.exampleNumber,
|
||||
paddingLength: template.paddingLength,
|
||||
resetAnnually: template.resetAnnually,
|
||||
isActive: template.isActive ?? true
|
||||
};
|
||||
const res = await apiClient.post<NumberingTemplate>('/admin/document-numbering/templates', payload);
|
||||
return res.data;
|
||||
},
|
||||
|
||||
getSequences: async (): Promise<NumberSequence[]> => {
|
||||
// TODO: Implement backend endpoint for sequences list
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => resolve([...mockSequences]), 500);
|
||||
setTimeout(() => resolve([]), 500);
|
||||
});
|
||||
},
|
||||
|
||||
generateTestNumber: async (templateId: number, context: { organizationId: string, disciplineId: string }): Promise<{ number: string }> => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
const template = mockTemplates.find(t => t.templateId === templateId);
|
||||
if (!template) return resolve({ number: 'ERROR' });
|
||||
// Use preview endpoint
|
||||
// We need to know projectId, typeId etc from template.
|
||||
// But preview endpoint needs context.
|
||||
// For now, let's just return a mock or call preview endpoint if we have enough info.
|
||||
|
||||
let format = template.templateFormat;
|
||||
// Mock replacement
|
||||
format = format.replace('{PROJECT}', 'LCBP3');
|
||||
format = format.replace('{ORIGINATOR}', context.organizationId === '1' ? 'PAT' : 'CN');
|
||||
format = format.replace('{RECIPIENT}', context.organizationId === '1' ? 'CN' : 'PAT');
|
||||
format = format.replace('{CORR_TYPE}', template.documentTypeName === 'Correspondence' ? 'CORR' : 'RFA');
|
||||
format = format.replace('{DISCIPLINE}', context.disciplineId === '1' ? 'STR' : (context.disciplineId === '2' ? 'ARC' : 'GEN'));
|
||||
format = format.replace('{RFA_TYPE}', 'SDW'); // Mock
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Generating test number for:', templateId, context);
|
||||
return new Promise((resolve) => resolve({ number: 'TEST-1234' }));
|
||||
},
|
||||
|
||||
const year = new Date().getFullYear();
|
||||
format = format.replace('{YEAR:A.D.}', year.toString());
|
||||
format = format.replace('{YEAR:B.E.}', (year + 543).toString());
|
||||
format = format.replace('{SEQ:4}', '0001');
|
||||
format = format.replace('{REV}', 'A');
|
||||
// --- Admin Tools ---
|
||||
|
||||
resolve({ number: format });
|
||||
}, 800);
|
||||
});
|
||||
}
|
||||
getMetrics: async (): Promise<{ audit: any[], errors: any[] }> => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const res = await apiClient.get<{ audit: any[], errors: any[] }>('/admin/document-numbering/metrics');
|
||||
return res.data;
|
||||
},
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
manualOverride: async (data: any): Promise<void> => {
|
||||
await apiClient.post('/admin/document-numbering/manual-override', data);
|
||||
},
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
voidAndReplace: async (data: any): Promise<string> => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const res = await apiClient.post<any>('/admin/document-numbering/void-and-replace', data);
|
||||
return res.data;
|
||||
},
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
cancelNumber: async (data: any): Promise<void> => {
|
||||
await apiClient.post('/admin/document-numbering/cancel', data);
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user