improvement: treatment exits contoll adde to appoinment remove action.
This commit is contained in:
@@ -63,6 +63,7 @@ export const ErrorCode = {
|
|||||||
CONFLICT: 'CONFLICT',
|
CONFLICT: 'CONFLICT',
|
||||||
CONFLICT_FUTURE_APPOINTMENTS: 'CONFLICT_FUTURE_APPOINTMENTS',
|
CONFLICT_FUTURE_APPOINTMENTS: 'CONFLICT_FUTURE_APPOINTMENTS',
|
||||||
APPOINTMENT_PATIENT_LOCKED: 'APPOINTMENT_PATIENT_LOCKED',
|
APPOINTMENT_PATIENT_LOCKED: 'APPOINTMENT_PATIENT_LOCKED',
|
||||||
|
APPOINTMENT_HAS_TREATMENT: 'APPOINTMENT_HAS_TREATMENT',
|
||||||
BAD_REQUEST: 'BAD_REQUEST',
|
BAD_REQUEST: 'BAD_REQUEST',
|
||||||
INTERNAL_ERROR: 'INTERNAL_ERROR',
|
INTERNAL_ERROR: 'INTERNAL_ERROR',
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
ForbiddenException,
|
ForbiddenException,
|
||||||
|
HttpStatus,
|
||||||
Injectable,
|
Injectable,
|
||||||
NotFoundException,
|
NotFoundException,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
@@ -16,6 +17,7 @@ import { ListAppointmentsDto } from './dto/list-appointments.dto';
|
|||||||
import { UpdateAppointmentDto } from './dto/update-appointment.dto';
|
import { UpdateAppointmentDto } from './dto/update-appointment.dto';
|
||||||
import { TreatmentCatalogService } from '../treatment-catalog/treatment-catalog.service';
|
import { TreatmentCatalogService } from '../treatment-catalog/treatment-catalog.service';
|
||||||
import { hasEffectivePermission } from '../../common/membership-permissions';
|
import { hasEffectivePermission } from '../../common/membership-permissions';
|
||||||
|
import { AppException, ErrorCode } from '../../common/errors';
|
||||||
|
|
||||||
const MS_PER_DAY = 86_400_000;
|
const MS_PER_DAY = 86_400_000;
|
||||||
|
|
||||||
@@ -215,9 +217,7 @@ export class AppointmentsService {
|
|||||||
select: { id: true },
|
select: { id: true },
|
||||||
});
|
});
|
||||||
if (linkedTreatment) {
|
if (linkedTreatment) {
|
||||||
throw new BadRequestException(
|
throw new AppException(ErrorCode.APPOINTMENT_PATIENT_LOCKED, HttpStatus.CONFLICT);
|
||||||
'Cannot change the patient while a treatment is linked to this appointment',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,13 +256,17 @@ export class AppointmentsService {
|
|||||||
|
|
||||||
const existing = await this.prisma.appointment.findFirst({
|
const existing = await this.prisma.appointment.findFirst({
|
||||||
where: { id, organizationId },
|
where: { id, organizationId },
|
||||||
select: { id: true },
|
select: { id: true, treatment: { select: { id: true } } },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!existing) {
|
if (!existing) {
|
||||||
throw new NotFoundException('Appointment not found');
|
throw new NotFoundException('Appointment not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (existing.treatment) {
|
||||||
|
throw new AppException(ErrorCode.APPOINTMENT_HAS_TREATMENT, HttpStatus.CONFLICT);
|
||||||
|
}
|
||||||
|
|
||||||
await this.prisma.appointment.delete({
|
await this.prisma.appointment.delete({
|
||||||
where: { id },
|
where: { id },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -582,6 +582,7 @@
|
|||||||
"confirmRemove": "Remove this appointment?",
|
"confirmRemove": "Remove this appointment?",
|
||||||
"successRemoved": "Appointment removed.",
|
"successRemoved": "Appointment removed.",
|
||||||
"errorDelete": "Could not delete appointment.",
|
"errorDelete": "Could not delete appointment.",
|
||||||
|
"deleteBlockedHint": "This appointment cannot be deleted because a treatment is linked to it.",
|
||||||
"errorLoadSchedule": "Failed to load schedule.",
|
"errorLoadSchedule": "Failed to load schedule.",
|
||||||
"successPatientSaved": "Patient {firstName} {lastName} was saved.",
|
"successPatientSaved": "Patient {firstName} {lastName} was saved.",
|
||||||
"searchPlaceholder": "Search existing patients",
|
"searchPlaceholder": "Search existing patients",
|
||||||
@@ -1013,6 +1014,7 @@
|
|||||||
"CONFLICT": "This action conflicts with existing data.",
|
"CONFLICT": "This action conflicts with existing data.",
|
||||||
"CONFLICT_FUTURE_APPOINTMENTS": "You cannot stop participating in treatments while you have future appointments. Reassign or cancel them first.",
|
"CONFLICT_FUTURE_APPOINTMENTS": "You cannot stop participating in treatments while you have future appointments. Reassign or cancel them first.",
|
||||||
"APPOINTMENT_PATIENT_LOCKED": "Cannot change the patient while a treatment is linked to this appointment.",
|
"APPOINTMENT_PATIENT_LOCKED": "Cannot change the patient while a treatment is linked to this appointment.",
|
||||||
|
"APPOINTMENT_HAS_TREATMENT": "This appointment cannot be deleted because a treatment is linked to it.",
|
||||||
"BAD_REQUEST": "The request could not be processed.",
|
"BAD_REQUEST": "The request could not be processed.",
|
||||||
"INTERNAL_ERROR": "Something went wrong on our end. Please try again later."
|
"INTERNAL_ERROR": "Something went wrong on our end. Please try again later."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -583,6 +583,7 @@
|
|||||||
"confirmRemove": "این نوبت حذف شود؟",
|
"confirmRemove": "این نوبت حذف شود؟",
|
||||||
"successRemoved": "نوبت حذف شد.",
|
"successRemoved": "نوبت حذف شد.",
|
||||||
"errorDelete": "حذف نوبت امکانپذیر نبود.",
|
"errorDelete": "حذف نوبت امکانپذیر نبود.",
|
||||||
|
"deleteBlockedHint": "بهدلیل وجود درمان مرتبط با این نوبت، امکان حذف آن وجود ندارد.",
|
||||||
"errorLoadSchedule": "بارگذاری برنامه ناموفق بود.",
|
"errorLoadSchedule": "بارگذاری برنامه ناموفق بود.",
|
||||||
"successPatientSaved": "بیمار {firstName} {lastName} ذخیره شد.",
|
"successPatientSaved": "بیمار {firstName} {lastName} ذخیره شد.",
|
||||||
"searchPlaceholder": "جستجوی بیماران موجود",
|
"searchPlaceholder": "جستجوی بیماران موجود",
|
||||||
@@ -1014,6 +1015,7 @@
|
|||||||
"CONFLICT": "این عمل با دادههای موجود در تضاد است.",
|
"CONFLICT": "این عمل با دادههای موجود در تضاد است.",
|
||||||
"CONFLICT_FUTURE_APPOINTMENTS": "تا وقتی نوبتهای آینده دارید نمیتوانید مشارکت در درمان را متوقف کنید. ابتدا آنها را لغو یا واگذار کنید.",
|
"CONFLICT_FUTURE_APPOINTMENTS": "تا وقتی نوبتهای آینده دارید نمیتوانید مشارکت در درمان را متوقف کنید. ابتدا آنها را لغو یا واگذار کنید.",
|
||||||
"APPOINTMENT_PATIENT_LOCKED": "تا وقتی درمانی به این نوبت متصل است، امکان تغییر بیمار وجود ندارد.",
|
"APPOINTMENT_PATIENT_LOCKED": "تا وقتی درمانی به این نوبت متصل است، امکان تغییر بیمار وجود ندارد.",
|
||||||
|
"APPOINTMENT_HAS_TREATMENT": "بهدلیل وجود درمان مرتبط با این نوبت، امکان حذف آن وجود ندارد.",
|
||||||
"BAD_REQUEST": "درخواست قابل پردازش نبود.",
|
"BAD_REQUEST": "درخواست قابل پردازش نبود.",
|
||||||
"INTERNAL_ERROR": "مشکلی در سرور رخ داد. لطفاً بعداً تلاش کنید."
|
"INTERNAL_ERROR": "مشکلی در سرور رخ داد. لطفاً بعداً تلاش کنید."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -582,6 +582,7 @@
|
|||||||
"confirmRemove": "Deze afspraak verwijderen?",
|
"confirmRemove": "Deze afspraak verwijderen?",
|
||||||
"successRemoved": "Afspraak verwijderd.",
|
"successRemoved": "Afspraak verwijderd.",
|
||||||
"errorDelete": "Kon afspraak niet verwijderen.",
|
"errorDelete": "Kon afspraak niet verwijderen.",
|
||||||
|
"deleteBlockedHint": "Deze afspraak kan niet worden verwijderd omdat er een behandeling aan is gekoppeld.",
|
||||||
"errorLoadSchedule": "Rooster laden mislukt.",
|
"errorLoadSchedule": "Rooster laden mislukt.",
|
||||||
"successPatientSaved": "Patiënt {firstName} {lastName} is opgeslagen.",
|
"successPatientSaved": "Patiënt {firstName} {lastName} is opgeslagen.",
|
||||||
"searchPlaceholder": "Bestaande patiënten zoeken",
|
"searchPlaceholder": "Bestaande patiënten zoeken",
|
||||||
@@ -1013,6 +1014,7 @@
|
|||||||
"CONFLICT": "Deze actie conflicteert met bestaande gegevens.",
|
"CONFLICT": "Deze actie conflicteert met bestaande gegevens.",
|
||||||
"CONFLICT_FUTURE_APPOINTMENTS": "U kunt niet stoppen met deelnemen aan behandelingen zolang u toekomstige afspraken hebt. Wijs ze eerst opnieuw toe of annuleer ze.",
|
"CONFLICT_FUTURE_APPOINTMENTS": "U kunt niet stoppen met deelnemen aan behandelingen zolang u toekomstige afspraken hebt. Wijs ze eerst opnieuw toe of annuleer ze.",
|
||||||
"APPOINTMENT_PATIENT_LOCKED": "De patiënt kan niet worden gewijzigd zolang er een behandeling aan deze afspraak is gekoppeld.",
|
"APPOINTMENT_PATIENT_LOCKED": "De patiënt kan niet worden gewijzigd zolang er een behandeling aan deze afspraak is gekoppeld.",
|
||||||
|
"APPOINTMENT_HAS_TREATMENT": "Deze afspraak kan niet worden verwijderd omdat er een behandeling aan is gekoppeld.",
|
||||||
"BAD_REQUEST": "Het verzoek kon niet worden verwerkt.",
|
"BAD_REQUEST": "Het verzoek kon niet worden verwerkt.",
|
||||||
"INTERNAL_ERROR": "Er is iets misgegaan aan onze kant. Probeer het later opnieuw."
|
"INTERNAL_ERROR": "Er is iets misgegaan aan onze kant. Probeer het later opnieuw."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -310,6 +310,10 @@ export function AppointmentBookingModal({
|
|||||||
|
|
||||||
{error && <p className="text-sm text-red-400">{error}</p>}
|
{error && <p className="text-sm text-red-400">{error}</p>}
|
||||||
|
|
||||||
|
{editingAppointment?.hasTreatment ? (
|
||||||
|
<p className="text-sm text-text-secondary">{t('deleteBlockedHint')}</p>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<div className="flex flex-col-reverse gap-2 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between">
|
<div className="flex flex-col-reverse gap-2 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between">
|
||||||
{editingAppointment && canDelete && onDelete ? (
|
{editingAppointment && canDelete && onDelete ? (
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -279,7 +279,12 @@ export function AppointmentsPage() {
|
|||||||
}}
|
}}
|
||||||
onSubmit={handleSaveAppointment}
|
onSubmit={handleSaveAppointment}
|
||||||
loading={savingAppointment}
|
loading={savingAppointment}
|
||||||
|
canDelete={
|
||||||
|
canManageAppointments &&
|
||||||
|
!isViewingPastDay &&
|
||||||
|
!!activeEditingAppointment &&
|
||||||
|
!activeEditingAppointment.hasTreatment
|
||||||
|
}
|
||||||
onDelete={() => void handleDeleteEditingAppointment()}
|
onDelete={() => void handleDeleteEditingAppointment()}
|
||||||
deleting={deletingAppointment}
|
deleting={deletingAppointment}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user