TreatmentType and ProsthesisType database shcema and data updated. Lab dispatch wired through new data.

This commit is contained in:
2026-07-06 20:40:19 +03:30
parent 3e81c110a3
commit 667b08ed0c
48 changed files with 1813 additions and 275 deletions

View File

@@ -9,7 +9,7 @@ import { PastTreatmentsPanel } from '@/components/ui/treatment/PastTreatmentsPan
import { TreatmentDetailsEditor } from '@/components/ui/treatment/TreatmentDetailsEditor';
import { TreatmentPreviewCard } from '@/components/ui/treatment/TreatmentPreviewCard';
import { ToastStack } from '@/components/ui/shared/Toast';
import { treatmentTypeLabelKey } from '@/components/ui/treatment/treatmentTypeDisplay';
import { treatmentTypeLabelFromCatalog } from '@/components/ui/treatment/treatmentTypeDisplay';
import {
addCalendarDays,
compareLocalDayStart,
@@ -25,6 +25,7 @@ import { formatApiErrorMessage } from '@/components/shared/formatApiError';
import { useToast } from '@/lib/hooks/useToast';
import type { Organization } from '@/types/organization';
import type { AppointmentRecord } from '@/types/appointment';
import type { TreatmentCatalogEntry } from '@/types/treatment-catalog';
import type {
FdiToothId,
LabCaseDraft,
@@ -93,7 +94,7 @@ function newDetail(): TreatmentDetailDraft {
typeof crypto !== 'undefined' && 'randomUUID' in crypto
? crypto.randomUUID()
: `detail-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
treatmentType: 'consultation',
treatmentType: 'restoration',
teeth: [],
comment: '',
attachmentMetas: [],
@@ -111,6 +112,7 @@ function newLabCaseDraft(): LabCaseDraft {
destinationOrganizationId: null,
labComment: '',
detailClientIds: [],
toothProsthesis: [],
sentAt: null,
sends: [],
};
@@ -145,12 +147,20 @@ function mapDetailFromApi(d: PastTreatmentCase): TreatmentDetailDraft {
}
function mapLabCaseDraftFromApi(lc: PastLabCase): LabCaseDraft {
const detailClientById = new Map(lc.details.map((d) => [d.id, d.clientId]));
return {
clientId: lc.clientId,
id: lc.id,
destinationOrganizationId: lc.destinationOrganizationId,
labComment: lc.labComment ?? '',
detailClientIds: lc.details.map((d) => d.clientId),
toothProsthesis: (lc.toothProsthesis ?? []).map((tp) => ({
detailClientId:
detailClientById.get(tp.treatmentDetailId) ?? tp.treatmentDetailId,
tooth: tp.tooth,
prosthesisTypeCode: tp.prosthesisTypeCode,
})),
sentAt: lc.sentAt ?? null,
sends: lc.sends ?? [],
};
@@ -231,6 +241,7 @@ export function TreatmentWorkspace({ userId, currentOrganization }: TreatmentWor
const [orgs, setOrgs] = useState<LinkedOrganizationOption[]>([]);
const [labDependentCodes, setLabDependentCodes] = useState<Set<string>>(new Set());
const [treatmentCatalog, setTreatmentCatalog] = useState<TreatmentCatalogEntry[]>([]);
const [details, setDetails] = useState<TreatmentDetailDraft[]>(() => [newDetail()]);
const [labCaseDrafts, setLabCaseDrafts] = useState<LabCaseDraft[]>([]);
@@ -414,6 +425,7 @@ export function TreatmentWorkspace({ userId, currentOrganization }: TreatmentWor
]);
if (cancelled) return;
setOrgs(orgsResponse.data);
setTreatmentCatalog(catalogResponse.data);
setLabDependentCodes(
new Set(catalogResponse.data.filter((entry) => entry.labDependent).map((entry) => entry.code)),
);
@@ -765,6 +777,17 @@ export function TreatmentWorkspace({ userId, currentOrganization }: TreatmentWor
treatmentDetailIds: lc.detailClientIds
.map((clientId) => detailIdByClientId.get(clientId))
.filter((id): id is string => Boolean(id)),
toothProsthesis: lc.toothProsthesis
.map((tp) => {
const detailId = detailIdByClientId.get(tp.detailClientId);
if (!detailId) return null;
return {
treatmentDetailId: detailId,
tooth: tp.tooth,
prosthesisTypeCode: tp.prosthesisTypeCode,
};
})
.filter((row): row is { treatmentDetailId: string; tooth: string; prosthesisTypeCode: string } => row !== null),
}));
if (payload.length === 0) {
@@ -881,6 +904,7 @@ export function TreatmentWorkspace({ userId, currentOrganization }: TreatmentWor
appointments={appointments}
selectedAppointmentId={selectedAppointmentId}
onSelectAppointment={onPickAppointment}
treatmentCatalog={treatmentCatalog}
loading={apptsLoading}
/>
@@ -906,10 +930,8 @@ export function TreatmentWorkspace({ userId, currentOrganization }: TreatmentWor
</p>
<p className="text-[11px] text-text-secondary">
{t('purposeLabel')}{' '}
<span className="capitalize text-text-primary">
{t(
treatmentTypeLabelKey(selectedAppointment.purpose) as 'typeConsultation',
)}
<span className="text-text-primary">
{treatmentTypeLabelFromCatalog(selectedAppointment.purpose, treatmentCatalog)}
</span>
</p>
</div>
@@ -922,6 +944,7 @@ export function TreatmentWorkspace({ userId, currentOrganization }: TreatmentWor
<TreatmentPreviewCard
treatment={previewTreatment}
labDependentCodes={labDependentCodes}
treatmentCatalog={treatmentCatalog}
orgs={orgs}
openDisabled={isPreviewAlreadyOpen}
onOpen={handleOpenTreatment}
@@ -929,6 +952,7 @@ export function TreatmentWorkspace({ userId, currentOrganization }: TreatmentWor
<PastTreatmentsPanel
items={historyPanelItems}
treatmentCatalog={treatmentCatalog}
loading={historyLoading}
selectedPreviewId={selectedPreviewId}
onSelectTreatment={handleSelectPreviewTreatment}
@@ -960,6 +984,7 @@ export function TreatmentWorkspace({ userId, currentOrganization }: TreatmentWor
onDetailsChange={setDetails}
isDetailLocked={isDetailLocked}
labDependentCodes={labDependentCodes}
treatmentCatalog={treatmentCatalog}
disabled={!canEditTreatmentForDay}
canEdit={canEdit}
saveStatus={saveStatus}
@@ -976,6 +1001,7 @@ export function TreatmentWorkspace({ userId, currentOrganization }: TreatmentWor
details={details}
labCases={labCaseDrafts}
labDependentCodes={labDependentCodes}
treatmentCatalog={treatmentCatalog}
activeLabCaseId={activeLabCaseId}
onActiveLabCaseChange={setActiveLabCaseId}
onLabCasesChange={setLabCaseDrafts}