improvement: task assignment flow added. cases and tasks feature updated accordingly.
This commit is contained in:
@@ -14,8 +14,9 @@ import {
|
||||
} from '../catalog/catalog-label.service';
|
||||
import { TreatmentCatalogService } from '../treatment-catalog/treatment-catalog.service';
|
||||
import { normalizeTeeth } from '../treatments/treatment.utils';
|
||||
import { ListLabCasesDto, UpdateLabCaseImportantDto } from './dto/cases.dto';
|
||||
import { ListLabCasesDto, UpdateLabCaseImportantDto, AssignLabCaseTaskDto } from './dto/cases.dto';
|
||||
import { normalizeTaskTeeth } from './lab-case-task.util';
|
||||
import { hasEffectivePermission } from '../../common/membership-permissions';
|
||||
|
||||
const labCaseListInclude = {
|
||||
treatment: {
|
||||
@@ -49,6 +50,7 @@ const labCaseListInclude = {
|
||||
],
|
||||
include: {
|
||||
lastStatusChangedBy: { select: { id: true, name: true } },
|
||||
assignee: { select: { id: true, name: true } },
|
||||
statusEvents: {
|
||||
orderBy: { changedAt: 'asc' as const },
|
||||
include: { changedBy: { select: { id: true, name: true } } },
|
||||
@@ -74,6 +76,7 @@ const labCaseListInclude = {
|
||||
type LabCaseTaskWithRelations = Prisma.LabCaseTaskGetPayload<{
|
||||
include: {
|
||||
lastStatusChangedBy: { select: { id: true; name: true } };
|
||||
assignee: { select: { id: true; name: true } };
|
||||
statusEvents: {
|
||||
include: { changedBy: { select: { id: true; name: true } } };
|
||||
};
|
||||
@@ -370,6 +373,95 @@ export class CasesService {
|
||||
return { success: true, data: await this.mapLabCaseDetail(labCase, localeInput) };
|
||||
}
|
||||
|
||||
async listAssignableStaff(labOrganizationId: string, actorUserId: string) {
|
||||
await this.assertCanEditCases(actorUserId, labOrganizationId);
|
||||
|
||||
const memberships = await this.prisma.membership.findMany({
|
||||
where: {
|
||||
organizationId: labOrganizationId,
|
||||
OR: [{ isOwner: true }, { isActive: true }],
|
||||
},
|
||||
include: {
|
||||
permissions: { include: { permission: true } },
|
||||
organization: { include: { type: true, plan: true } },
|
||||
user: { select: { id: true, name: true } },
|
||||
},
|
||||
});
|
||||
|
||||
const staff = memberships
|
||||
.filter((m) => hasEffectivePermission(m, 'TAB_TASKS_EDIT'))
|
||||
.map((m) => ({
|
||||
id: m.user.id,
|
||||
name: m.user.name,
|
||||
}))
|
||||
.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
return { success: true, data: staff };
|
||||
}
|
||||
|
||||
async assignTask(
|
||||
labCaseId: string,
|
||||
taskId: string,
|
||||
dto: AssignLabCaseTaskDto,
|
||||
labOrganizationId: string,
|
||||
actorUserId: string,
|
||||
localeInput?: string | null,
|
||||
) {
|
||||
await this.assertCanEditCases(actorUserId, labOrganizationId);
|
||||
|
||||
const task = await this.prisma.labCaseTask.findFirst({
|
||||
where: {
|
||||
id: taskId,
|
||||
labCaseId,
|
||||
labCase: {
|
||||
sentAt: { not: null },
|
||||
sends: { some: { organizationId: labOrganizationId } },
|
||||
},
|
||||
},
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
if (!task) {
|
||||
throw new NotFoundException('Task not found');
|
||||
}
|
||||
|
||||
const assigneeUserId = dto.assigneeUserId ?? null;
|
||||
|
||||
if (assigneeUserId) {
|
||||
const memberships = await this.prisma.membership.findMany({
|
||||
where: {
|
||||
organizationId: labOrganizationId,
|
||||
userId: assigneeUserId,
|
||||
OR: [{ isOwner: true }, { isActive: true }],
|
||||
},
|
||||
include: {
|
||||
permissions: { include: { permission: true } },
|
||||
organization: { include: { type: true, plan: true } },
|
||||
},
|
||||
});
|
||||
|
||||
const canReceive = memberships.some((m) => hasEffectivePermission(m, 'TAB_TASKS_EDIT'));
|
||||
if (!canReceive) {
|
||||
throw new BadRequestException('Selected user cannot be assigned tasks');
|
||||
}
|
||||
}
|
||||
|
||||
await this.prisma.labCaseTask.update({
|
||||
where: { id: taskId },
|
||||
data: {
|
||||
assigneeUserId,
|
||||
assignedAt: assigneeUserId ? new Date() : null,
|
||||
},
|
||||
});
|
||||
|
||||
const labCase = await this.prisma.labCase.findFirstOrThrow({
|
||||
where: { id: labCaseId },
|
||||
include: labCaseListInclude,
|
||||
});
|
||||
|
||||
return { success: true, data: await this.mapLabCaseDetail(labCase, localeInput) };
|
||||
}
|
||||
|
||||
private buildListWhere(
|
||||
labOrganizationId: string,
|
||||
query: ListLabCasesDto,
|
||||
@@ -579,6 +671,10 @@ export class CasesService {
|
||||
stepOrder: task.stepOrder,
|
||||
stepLabel: task.stepLabel,
|
||||
status: task.status,
|
||||
assignee: task.assignee
|
||||
? { id: task.assignee.id, name: task.assignee.name }
|
||||
: null,
|
||||
assignedAt: task.assignedAt?.toISOString() ?? null,
|
||||
createdAt: task.createdAt.toISOString(),
|
||||
lastStatusChangedAt: task.lastStatusChangedAt?.toISOString() ?? null,
|
||||
lastStatusChangedBy: task.lastStatusChangedBy
|
||||
|
||||
Reference in New Issue
Block a user