260330:1630 Addied correspondence_revieion_attcahments table table #04
CI / CD Pipeline / build (push) Successful in 17m50s
CI / CD Pipeline / deploy (push) Successful in 7m12s

This commit is contained in:
admin
2026-03-30 16:30:24 +07:00
parent f9dbff7811
commit 4538c83010
+46 -33
View File
@@ -16,7 +16,7 @@ import { useCreateCorrespondence, useUpdateCorrespondence } from '@/hooks/use-co
import { Organization } from '@/types/organization'; import { Organization } from '@/types/organization';
import { useOrganizations, useProjects, useCorrespondenceTypes, useDisciplines, useContracts } from '@/hooks/use-master-data'; import { useOrganizations, useProjects, useCorrespondenceTypes, useDisciplines, useContracts } from '@/hooks/use-master-data';
import { CreateCorrespondenceDto } from '@/types/dto/correspondence/create-correspondence.dto'; import { CreateCorrespondenceDto } from '@/types/dto/correspondence/create-correspondence.dto';
import { useState, useEffect, useRef } from 'react'; import { useState, useEffect, useRef, useMemo } from 'react';
import { numberingApi } from '@/lib/api/numbering'; import { numberingApi } from '@/lib/api/numbering';
import { filesApi } from '@/lib/api/files'; import { filesApi } from '@/lib/api/files';
import { toast } from 'sonner'; import { toast } from 'sonner';
@@ -81,8 +81,11 @@ interface InitialCorrespondenceData {
project?: { publicId?: string }; project?: { publicId?: string };
contract?: { publicId?: string }; contract?: { publicId?: string };
correspondenceTypeId?: number; correspondenceTypeId?: number;
type?: { id?: number; publicId?: string };
disciplineId?: number; disciplineId?: number;
discipline?: { discipline?: {
id?: number;
publicId?: string;
contract?: { publicId?: string }; contract?: { publicId?: string };
}; };
revisions?: Array<{ revisions?: Array<{
@@ -167,51 +170,61 @@ export function CorrespondenceForm({
const selectedRevision = normalizedSelectedRevisionId const selectedRevision = normalizedSelectedRevisionId
? initialData?.revisions?.find((r) => normalizeUuid(r.publicId) === normalizedSelectedRevisionId) ? initialData?.revisions?.find((r) => normalizeUuid(r.publicId) === normalizedSelectedRevisionId)
: undefined; : undefined;
const currentRev = selectedRevision || initialData?.revisions?.find((r) => r.isCurrent) || initialData?.revisions?.[0]; const defaultValues = useMemo<Partial<FormData>>(() => {
const initialToRecipient = initialData?.recipients?.find((r) => r.recipientType === 'TO'); const currentRevision = selectedRevision || initialData?.revisions?.find((r) => r.isCurrent) || initialData?.revisions?.[0];
const initialCcRecipientIds = const initialToRecipient = initialData?.recipients?.find((r) => r.recipientType === 'TO');
initialData?.recipients const initialCcRecipientIds =
?.filter((r) => r.recipientType === 'CC') initialData?.recipients
.map((r) => normalizePublicId(r.recipientOrganization?.publicId)) ?.filter((r) => r.recipientType === 'CC')
.filter((value): value is string => Boolean(value)) ?? []; .map((r) => normalizePublicId(r.recipientOrganization?.publicId))
.filter((value): value is string => Boolean(value)) ?? [];
const defaultValues: Partial<FormData> = { return {
projectId: projectId:
normalizePublicId(initialData?.project?.publicId) ?? normalizePublicId(initialData?.project?.publicId) ??
normalizePublicId(initialData?.projectId), normalizePublicId((initialData as Record<string, unknown>)?.projectId),
// [FIX v1.8.1] correspondences ไม่มี contract_id โดยตรง → จะ auto-populate จาก discipline useEffect หรือจาก object contract เองในกรณี mock/test contractId:
contractId: normalizePublicId(initialData?.contract?.publicId) ??
normalizePublicId(initialData?.contract?.publicId) ?? normalizePublicId(initialData?.discipline?.contract?.publicId) ??
normalizePublicId(initialData?.discipline?.contract?.publicId) ?? normalizePublicId((initialData as Record<string, unknown>)?.contractId as string),
normalizePublicId((initialData as Record<string, unknown>)?.contractId as string), documentTypeId: initialData?.type?.id ?? initialData?.correspondenceTypeId,
documentTypeId: initialData?.correspondenceTypeId || undefined, disciplineId: initialData?.discipline?.id ?? initialData?.disciplineId,
disciplineId: initialData?.disciplineId || undefined, subject: currentRevision?.subject || currentRevision?.title || '',
subject: currentRev?.subject || currentRev?.title || '', description: currentRevision?.description || '',
description: currentRev?.description || '', body: currentRevision?.body || '',
body: currentRev?.body || '', remarks: currentRevision?.remarks || '',
remarks: currentRev?.remarks || '', dueDate: currentRevision?.dueDate ? new Date(currentRevision.dueDate).toISOString().split('T')[0] : undefined,
dueDate: currentRev?.dueDate ? new Date(currentRev.dueDate).toISOString().split('T')[0] : undefined, documentDate: currentRevision?.documentDate ? new Date(currentRevision.documentDate).toISOString().split('T')[0] : undefined,
documentDate: currentRev?.documentDate ? new Date(currentRev.documentDate).toISOString().split('T')[0] : undefined, issuedDate: currentRevision?.issuedDate ? new Date(currentRevision.issuedDate).toISOString().split('T')[0] : undefined,
issuedDate: currentRev?.issuedDate ? new Date(currentRev.issuedDate).toISOString().split('T')[0] : undefined, receivedDate: currentRevision?.receivedDate ? new Date(currentRevision.receivedDate).toISOString().split('T')[0] : undefined,
receivedDate: currentRev?.receivedDate ? new Date(currentRev.receivedDate).toISOString().split('T')[0] : undefined, fromOrganizationId:
fromOrganizationId: normalizePublicId(initialData?.originator?.publicId) ??
normalizePublicId(initialData?.originator?.publicId) ?? normalizePublicId(initialData?.originatorId), normalizePublicId((initialData as Record<string, unknown>)?.originatorId as string),
toOrganizationId: normalizePublicId(initialToRecipient?.recipientOrganization?.publicId), toOrganizationId: normalizePublicId(initialToRecipient?.recipientOrganization?.publicId),
ccOrganizationIds: initialCcRecipientIds, ccOrganizationIds: initialCcRecipientIds,
importance: currentRev?.details?.importance || 'NORMAL', importance: currentRevision?.details?.importance || 'NORMAL',
} as Partial<FormData>; } as Partial<FormData>;
}, [initialData, selectedRevision]);
const { const {
register, register,
handleSubmit, handleSubmit,
setValue, setValue,
watch, watch,
reset,
formState: { errors }, formState: { errors },
} = useForm<FormData>({ } = useForm<FormData>({
resolver: zodResolver(correspondenceSchema) as Resolver<FormData>, resolver: zodResolver(correspondenceSchema) as Resolver<FormData>,
defaultValues: defaultValues as FormData, defaultValues: defaultValues as FormData,
}); });
// Watch for dynamic updates of initialData to ensure form correctly populates
useEffect(() => {
if (initialData) {
reset(defaultValues as FormData);
}
}, [initialData, selectedRevisionId, reset, defaultValues]);
// Watch for controlled inputs // Watch for controlled inputs
const projectId = watch('projectId'); const projectId = watch('projectId');
const contractId = watch('contractId'); const contractId = watch('contractId');