2026-06-28 16:46:42 +03:30
|
|
|
import { apiClient } from './client';
|
|
|
|
|
import type {
|
2026-06-28 17:49:40 +03:30
|
|
|
CasesFilterOptions,
|
2026-07-13 15:47:32 +03:30
|
|
|
AssignableTaskStaff,
|
2026-08-19 15:05:58 +03:30
|
|
|
LabCaseAttachmentMeta,
|
2026-06-28 16:46:42 +03:30
|
|
|
LabCaseDetail,
|
|
|
|
|
ListLabCasesParams,
|
|
|
|
|
PaginatedLabCases,
|
|
|
|
|
} from '@/types/cases';
|
2026-08-19 15:05:58 +03:30
|
|
|
import type { LinkedOrganizationOption } from '@/types/treatment';
|
|
|
|
|
|
|
|
|
|
export interface LabInternalCaseLinePayload {
|
|
|
|
|
clientId: string;
|
|
|
|
|
id?: string;
|
|
|
|
|
teeth: string[];
|
|
|
|
|
toothSelectionGroups?: Array<{ groupId: string; kind: string; teeth: string[] }>;
|
|
|
|
|
comment?: string;
|
|
|
|
|
toothProsthesis?: Array<{
|
|
|
|
|
tooth: string;
|
|
|
|
|
prosthesisTypeCode: string;
|
|
|
|
|
selectionGroupId?: string;
|
|
|
|
|
}>;
|
|
|
|
|
attachmentIds?: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LabInternalCasePayload {
|
|
|
|
|
referringClinicName?: string | null;
|
|
|
|
|
referringDentistName?: string | null;
|
|
|
|
|
patientDisplayName?: string | null;
|
|
|
|
|
patientDisplayMobile?: string | null;
|
|
|
|
|
partnerClinicOrganizationId?: string | null;
|
|
|
|
|
dueDate?: string | null;
|
|
|
|
|
lines?: LabInternalCaseLinePayload[];
|
|
|
|
|
}
|
2026-06-28 16:46:42 +03:30
|
|
|
|
|
|
|
|
export const casesApi = {
|
|
|
|
|
list: async (
|
|
|
|
|
params: ListLabCasesParams = {},
|
|
|
|
|
): Promise<{ success: boolean; data: PaginatedLabCases }> => {
|
|
|
|
|
const response = await apiClient.get('/cases', { params });
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
2026-08-19 15:05:58 +03:30
|
|
|
create: async (
|
|
|
|
|
payload: LabInternalCasePayload = {},
|
|
|
|
|
): Promise<{ success: boolean; data: LabCaseDetail }> => {
|
|
|
|
|
const response = await apiClient.post('/cases', payload);
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
update: async (
|
|
|
|
|
id: string,
|
|
|
|
|
payload: LabInternalCasePayload,
|
|
|
|
|
): Promise<{ success: boolean; data: LabCaseDetail }> => {
|
|
|
|
|
const response = await apiClient.put(`/cases/${id}`, payload);
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
start: async (id: string): Promise<{ success: boolean; data: LabCaseDetail }> => {
|
|
|
|
|
const response = await apiClient.post(`/cases/${id}/start`);
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
2026-08-19 23:59:37 +03:30
|
|
|
deleteDraft: async (id: string): Promise<{ success: boolean }> => {
|
|
|
|
|
const response = await apiClient.delete(`/cases/${id}`);
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
2026-08-19 15:05:58 +03:30
|
|
|
uploadLineAttachments: async (
|
|
|
|
|
caseId: string,
|
|
|
|
|
lineClientId: string,
|
|
|
|
|
files: File[],
|
|
|
|
|
): Promise<{ success: boolean; data: LabCaseAttachmentMeta[] }> => {
|
|
|
|
|
const form = new FormData();
|
|
|
|
|
for (const file of files) {
|
|
|
|
|
form.append('files', file);
|
|
|
|
|
}
|
|
|
|
|
const response = await apiClient.post(
|
|
|
|
|
`/cases/${caseId}/lines/${encodeURIComponent(lineClientId)}/attachments`,
|
|
|
|
|
form,
|
|
|
|
|
{ headers: { 'Content-Type': 'multipart/form-data' }, timeout: 120_000 },
|
|
|
|
|
);
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
listLinkedClinics: async (): Promise<{ success: boolean; data: LinkedOrganizationOption[] }> => {
|
|
|
|
|
const response = await apiClient.get('/cases/linked-clinics');
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
2026-06-28 16:46:42 +03:30
|
|
|
getOne: async (id: string): Promise<{ success: boolean; data: LabCaseDetail }> => {
|
|
|
|
|
const response = await apiClient.get(`/cases/${id}`);
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
2026-06-28 17:49:40 +03:30
|
|
|
listFilterOptions: async (): Promise<{ success: boolean; data: CasesFilterOptions }> => {
|
|
|
|
|
const response = await apiClient.get('/cases/filter-options');
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
2026-07-13 15:47:32 +03:30
|
|
|
listAssignableStaff: async (): Promise<{ success: boolean; data: AssignableTaskStaff[] }> => {
|
|
|
|
|
const response = await apiClient.get('/cases/assignable-staff');
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
assignTask: async (
|
|
|
|
|
caseId: string,
|
|
|
|
|
taskId: string,
|
|
|
|
|
assigneeUserId: string | null,
|
|
|
|
|
): Promise<{ success: boolean; data: LabCaseDetail }> => {
|
|
|
|
|
const response = await apiClient.patch(`/cases/${caseId}/tasks/${taskId}/assign`, {
|
|
|
|
|
assigneeUserId,
|
|
|
|
|
});
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
2026-07-08 02:53:47 +03:30
|
|
|
setCaseImportant: async (
|
2026-06-28 16:46:42 +03:30
|
|
|
caseId: string,
|
2026-07-07 15:31:09 +03:30
|
|
|
isImportant: boolean,
|
2026-07-08 02:53:47 +03:30
|
|
|
): Promise<{ success: boolean; data: LabCaseDetail }> => {
|
|
|
|
|
const response = await apiClient.patch(`/cases/${caseId}/important`, { isImportant });
|
2026-06-28 16:46:42 +03:30
|
|
|
return response.data;
|
|
|
|
|
},
|
2026-07-07 18:43:10 +03:30
|
|
|
|
2026-07-18 22:00:44 +03:30
|
|
|
setCaseExternalCode: async (
|
|
|
|
|
caseId: string,
|
|
|
|
|
externalCode: string | null,
|
|
|
|
|
): Promise<{ success: boolean; data: LabCaseDetail }> => {
|
|
|
|
|
const response = await apiClient.patch(`/cases/${caseId}/external-code`, { externalCode });
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
2026-07-07 18:43:10 +03:30
|
|
|
getAttachmentFileBlob: async (caseId: string, attachmentId: string): Promise<Blob> => {
|
|
|
|
|
const response = await apiClient.get(`/cases/${caseId}/attachments/${attachmentId}/file`, {
|
|
|
|
|
responseType: 'blob',
|
|
|
|
|
timeout: 120_000,
|
|
|
|
|
});
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
2026-06-28 16:46:42 +03:30
|
|
|
};
|