improvement: new prosthesis type data structure implemented and finally working!
This commit is contained in:
@@ -133,7 +133,7 @@ describe('generateLabCaseTasks', () => {
|
||||
expect(stepCodes).toContain('milling_wet');
|
||||
});
|
||||
|
||||
it('groups teeth sharing a prosthesis in one detail, and keeps other prosthesis separate', async () => {
|
||||
it('keeps one task set per tooth even when they share a prosthesis', async () => {
|
||||
const pfmSteps = stepsFromSeed('pfm_crown');
|
||||
const zirconiaSteps = stepsFromSeed('monolithic_zirconia');
|
||||
const { tx, created } = buildMockTx({
|
||||
@@ -150,16 +150,24 @@ describe('generateLabCaseTasks', () => {
|
||||
|
||||
const count = await generateLabCaseTasks(tx as never, 'lab-case-group', 'en');
|
||||
|
||||
expect(count).toBe(pfmSteps.length + zirconiaSteps.length);
|
||||
expect(count).toBe(pfmSteps.length * 2 + zirconiaSteps.length);
|
||||
const rows = created as Array<{ teeth: string[]; prosthesisTypeCode: string }>;
|
||||
const pfmRows = rows.filter((r) => r.prosthesisTypeCode === 'pfm_crown');
|
||||
const pfm14 = rows.filter(
|
||||
(r) => r.prosthesisTypeCode === 'pfm_crown' && r.teeth.join() === '14',
|
||||
);
|
||||
const pfm15 = rows.filter(
|
||||
(r) => r.prosthesisTypeCode === 'pfm_crown' && r.teeth.join() === '15',
|
||||
);
|
||||
const zirconiaRows = rows.filter((r) => r.prosthesisTypeCode === 'monolithic_zirconia');
|
||||
|
||||
expect(pfmRows).toHaveLength(pfmSteps.length);
|
||||
expect(pfm14).toHaveLength(pfmSteps.length);
|
||||
expect(pfm15).toHaveLength(pfmSteps.length);
|
||||
expect(zirconiaRows).toHaveLength(zirconiaSteps.length);
|
||||
// Teeth sharing the prosthesis in the same detail are merged and sorted.
|
||||
expect(pfmRows.every((r) => JSON.stringify(r.teeth) === JSON.stringify(['14', '15']))).toBe(true);
|
||||
expect(zirconiaRows.every((r) => JSON.stringify(r.teeth) === JSON.stringify(['16']))).toBe(true);
|
||||
const uniqueKeys = new Set(
|
||||
rows.map((r) => `${r.teeth.join()}:${r.prosthesisTypeCode}`),
|
||||
);
|
||||
expect(uniqueKeys.size).toBe(3);
|
||||
});
|
||||
|
||||
it('omits packing and shipping for smile_design', async () => {
|
||||
@@ -181,12 +189,13 @@ describe('generateLabCaseTasks', () => {
|
||||
const stepCodes = (created as Array<{ workflowStepCode: string }>).map(
|
||||
(row) => row.workflowStepCode,
|
||||
);
|
||||
expect(stepCodes).toEqual(['intraoral_scan', 'design']);
|
||||
expect(stepCodes).not.toContain('packing');
|
||||
expect(stepCodes).not.toContain('shipping');
|
||||
expect(stepCodes).toContain('printer_resin');
|
||||
expect(stepCodes).not.toContain('printer_resin');
|
||||
});
|
||||
|
||||
it('merges teeth with the same prosthesis type across selection groups', async () => {
|
||||
it('keeps connected and single teeth as separate per-tooth task sets', async () => {
|
||||
const pfmSteps = stepsFromSeed('pfm_crown');
|
||||
const { tx, created } = buildMockTx({
|
||||
toothProsthesisRows: [
|
||||
@@ -213,12 +222,10 @@ describe('generateLabCaseTasks', () => {
|
||||
});
|
||||
|
||||
const count = await generateLabCaseTasks(tx as never, 'lab-case-merge', 'en');
|
||||
expect(count).toBe(pfmSteps.length);
|
||||
expect(count).toBe(pfmSteps.length * 3);
|
||||
const rows = created as Array<{ teeth: string[]; prosthesisTypeCode: string }>;
|
||||
expect(rows).toHaveLength(pfmSteps.length);
|
||||
expect(rows.every((r) => JSON.stringify(r.teeth) === JSON.stringify(['14', '15', '21']))).toBe(
|
||||
true,
|
||||
);
|
||||
const teethSets = new Set(rows.map((r) => r.teeth.join(',')));
|
||||
expect(teethSets).toEqual(new Set(['14', '15', '21']));
|
||||
});
|
||||
|
||||
it('skips generation when tasks already exist', async () => {
|
||||
@@ -255,12 +262,56 @@ describe('generateLabCaseTasks', () => {
|
||||
});
|
||||
|
||||
const count = await generateLabCaseTasks(tx as never, 'lab-internal-1', 'en');
|
||||
expect(count).toBe(pfmSteps.length);
|
||||
expect(count).toBe(pfmSteps.length * 2);
|
||||
const rows = created as Array<{ teeth: string[]; lineId: string }>;
|
||||
const teethSets = new Set(rows.map((r) => r.teeth.join(',')));
|
||||
expect(teethSets).toEqual(new Set(['11', '21']));
|
||||
expect(created[0]).toMatchObject({
|
||||
lineId: 'line-1',
|
||||
sourceKey: 'line-1',
|
||||
treatmentDetailId: null,
|
||||
teeth: ['11', '21'],
|
||||
});
|
||||
});
|
||||
|
||||
it('unions stacked types on the same tooth and de-dupes scan/pack/ship', async () => {
|
||||
const tiSteps = stepsFromSeed('ti_base_abutment');
|
||||
const zrSteps = stepsFromSeed('monolithic_zirconia');
|
||||
const { tx, created } = buildMockTx({
|
||||
toothProsthesisRows: [
|
||||
{
|
||||
treatmentDetailId: 'detail-1',
|
||||
tooth: '46',
|
||||
prosthesisTypeCode: 'ti_base_abutment',
|
||||
},
|
||||
{
|
||||
treatmentDetailId: 'detail-1',
|
||||
tooth: '46',
|
||||
prosthesisTypeCode: 'monolithic_zirconia',
|
||||
},
|
||||
],
|
||||
prosthesisTypes: [
|
||||
{ code: 'ti_base_abutment', steps: tiSteps },
|
||||
{ code: 'monolithic_zirconia', steps: zrSteps },
|
||||
],
|
||||
});
|
||||
|
||||
const count = await generateLabCaseTasks(tx as never, 'lab-case-stack', 'en');
|
||||
const rows = created as Array<{
|
||||
workflowStepCode: string;
|
||||
prosthesisTypeCode: string;
|
||||
teeth: string[];
|
||||
}>;
|
||||
expect(count).toBe(rows.length);
|
||||
expect(rows.every((r) => r.teeth.join() === '46')).toBe(true);
|
||||
expect(rows[0].prosthesisTypeCode).toBe('monolithic_zirconia+ti_base_abutment');
|
||||
const stepCodes = rows.map((r) => r.workflowStepCode);
|
||||
expect(stepCodes.filter((c) => c === 'intraoral_scan')).toHaveLength(1);
|
||||
expect(stepCodes.filter((c) => c === 'packing')).toHaveLength(1);
|
||||
expect(stepCodes.filter((c) => c === 'shipping')).toHaveLength(1);
|
||||
expect(stepCodes[0]).toBe('intraoral_scan');
|
||||
expect(stepCodes[stepCodes.length - 1]).toBe('shipping');
|
||||
expect(stepCodes).toContain('milling_dry');
|
||||
expect(stepCodes).toContain('sinter');
|
||||
expect(stepCodes).toContain('polish_prep');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user