сделал конвертацию запланированного приема в обычный прием
This commit is contained in:
parent
d101036445
commit
55369ac1a4
@ -11,7 +11,7 @@ from app.domain.entities.user import UserEntity
|
|||||||
class ScheduledAppointmentEntity(BaseModel):
|
class ScheduledAppointmentEntity(BaseModel):
|
||||||
id: Optional[int] = None
|
id: Optional[int] = None
|
||||||
scheduled_datetime: datetime.datetime
|
scheduled_datetime: datetime.datetime
|
||||||
is_canceled: bool
|
is_canceled: Optional[bool] = False
|
||||||
|
|
||||||
patient_id: int
|
patient_id: int
|
||||||
doctor_id: Optional[int] = None
|
doctor_id: Optional[int] = None
|
||||||
|
|||||||
@ -131,7 +131,6 @@ const AppointmentsPage = () => {
|
|||||||
</FloatButton.Group>
|
</FloatButton.Group>
|
||||||
|
|
||||||
<AppointmentFormModal
|
<AppointmentFormModal
|
||||||
visible={appointmentsPageUI.modalVisible}
|
|
||||||
onCancel={handleCancelModal}
|
onCancel={handleCancelModal}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@ -1,20 +1,13 @@
|
|||||||
// useAppointmentCalendarUI.js
|
|
||||||
import {useDispatch, useSelector} from "react-redux";
|
import {useDispatch, useSelector} from "react-redux";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import utc from "dayjs/plugin/utc";
|
import utc from "dayjs/plugin/utc";
|
||||||
import timezone from "dayjs/plugin/timezone";
|
import timezone from "dayjs/plugin/timezone";
|
||||||
import {Form, Grid, notification} from "antd";
|
import {Grid} from "antd";
|
||||||
import {
|
import {
|
||||||
closeModal,
|
|
||||||
openModal, setSelectedAppointment,
|
openModal, setSelectedAppointment,
|
||||||
setSelectedAppointments,
|
setSelectedAppointments,
|
||||||
setSelectedDate, setSelectedScheduledAppointment,
|
setSelectedScheduledAppointment,
|
||||||
} from "../../../../../Redux/Slices/appointmentsSlice.js";
|
} from "../../../../../Redux/Slices/appointmentsSlice.js";
|
||||||
import {useCreateAppointmentMutation, useUpdateAppointmentMutation} from "../../../../../Api/appointmentsApi.js";
|
|
||||||
import {
|
|
||||||
useCreateScheduledAppointmentMutation,
|
|
||||||
useUpdateScheduledAppointmentMutation
|
|
||||||
} from "../../../../../Api/scheduledAppointmentsApi.js";
|
|
||||||
|
|
||||||
dayjs.extend(utc);
|
dayjs.extend(utc);
|
||||||
dayjs.extend(timezone);
|
dayjs.extend(timezone);
|
||||||
@ -24,12 +17,6 @@ const {useBreakpoint} = Grid;
|
|||||||
|
|
||||||
const useAppointmentCalendarUI = (appointments, scheduledAppointments) => {
|
const useAppointmentCalendarUI = (appointments, scheduledAppointments) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const {
|
|
||||||
modalVisible,
|
|
||||||
selectedAppointments,
|
|
||||||
selectedAppointment,
|
|
||||||
selectedScheduledAppointment,
|
|
||||||
} = useSelector(state => state.appointmentsUI);
|
|
||||||
const selectedDate = dayjs.tz(useSelector(state => state.appointmentsUI.selectedDate), 'Europe/Moscow');
|
const selectedDate = dayjs.tz(useSelector(state => state.appointmentsUI.selectedDate), 'Europe/Moscow');
|
||||||
|
|
||||||
const screens = useBreakpoint();
|
const screens = useBreakpoint();
|
||||||
@ -39,7 +26,7 @@ const useAppointmentCalendarUI = (appointments, scheduledAppointments) => {
|
|||||||
|
|
||||||
const onSelect = (date) => {
|
const onSelect = (date) => {
|
||||||
const selectedDateStr = date.format('YYYY-MM-DD');
|
const selectedDateStr = date.format('YYYY-MM-DD');
|
||||||
dispatch(setSelectedDate(selectedDateStr));
|
// dispatch(setSelectedDate(selectedDateStr));
|
||||||
|
|
||||||
const appointmentsForDate = appointments.filter(app =>
|
const appointmentsForDate = appointments.filter(app =>
|
||||||
dayjs(app.appointment_datetime).format('YYYY-MM-DD') === selectedDateStr
|
dayjs(app.appointment_datetime).format('YYYY-MM-DD') === selectedDateStr
|
||||||
@ -62,10 +49,9 @@ const useAppointmentCalendarUI = (appointments, scheduledAppointments) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getAppointmentsByListAndDate = (list, value, isScheduled = false) => {
|
const getAppointmentsByListAndDate = (list, value, isScheduled = false) => {
|
||||||
const date = value.tz('Europe/Moscow').format('YYYY-MM-DD');
|
const date = value.format('YYYY-MM-DD');
|
||||||
return list.filter(app =>
|
return list.filter(app =>
|
||||||
dayjs(isScheduled ? app.scheduled_datetime : app.appointment_datetime)
|
dayjs(isScheduled ? app.scheduled_datetime : app.appointment_datetime)
|
||||||
.tz('Europe/Moscow')
|
|
||||||
.format('YYYY-MM-DD') === date
|
.format('YYYY-MM-DD') === date
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -28,6 +28,7 @@ const AppointmentFormModal = ({onCancel}) => {
|
|||||||
onCancel,
|
onCancel,
|
||||||
appointmentFormModalData.createAppointment,
|
appointmentFormModalData.createAppointment,
|
||||||
appointmentFormModalData.patients,
|
appointmentFormModalData.patients,
|
||||||
|
appointmentFormModalData.cancelAppointment,
|
||||||
);
|
);
|
||||||
|
|
||||||
const editor = useRef(null);
|
const editor = useRef(null);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import {useGetPatientsQuery} from "../../../../../Api/patientsApi.js";
|
import {useGetPatientsQuery} from "../../../../../Api/patientsApi.js";
|
||||||
import {useGetAppointmentTypesQuery} from "../../../../../Api/appointmentTypesApi.js";
|
import {useGetAppointmentTypesQuery} from "../../../../../Api/appointmentTypesApi.js";
|
||||||
import {useCreateAppointmentMutation, useUpdateAppointmentMutation} from "../../../../../Api/appointmentsApi.js";
|
import {useCreateAppointmentMutation, useUpdateAppointmentMutation} from "../../../../../Api/appointmentsApi.js";
|
||||||
|
import {useCancelScheduledAppointmentMutation} from "../../../../../Api/scheduledAppointmentsApi.js";
|
||||||
|
|
||||||
const useAppointmentFormModal = () => {
|
const useAppointmentFormModal = () => {
|
||||||
const {
|
const {
|
||||||
@ -19,11 +20,13 @@ const useAppointmentFormModal = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const [createAppointment, {isLoading: isCreating, isError: isErrorCreating}] = useCreateAppointmentMutation();
|
const [createAppointment, {isLoading: isCreating, isError: isErrorCreating}] = useCreateAppointmentMutation();
|
||||||
|
const [cancelAppointment] = useCancelScheduledAppointmentMutation();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
patients,
|
patients,
|
||||||
appointmentTypes,
|
appointmentTypes,
|
||||||
createAppointment,
|
createAppointment,
|
||||||
|
cancelAppointment,
|
||||||
isLoading: isLoadingPatients || isLoadingAppointmentTypes || isCreating,
|
isLoading: isLoadingPatients || isLoadingAppointmentTypes || isCreating,
|
||||||
isError: isErrorPatients || isErrorAppointmentTypes || isErrorCreating,
|
isError: isErrorPatients || isErrorAppointmentTypes || isErrorCreating,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import {Form, notification} from "antd";
|
import {Form, notification} from "antd";
|
||||||
import {useDispatch, useSelector} from "react-redux";
|
import {useDispatch, useSelector} from "react-redux";
|
||||||
import {closeModal} from "../../../../../Redux/Slices/appointmentsSlice.js";
|
import {closeModal, setSelectedScheduledAppointment} from "../../../../../Redux/Slices/appointmentsSlice.js";
|
||||||
import {useEffect, useMemo, useState} from "react";
|
import {useEffect, useMemo, useState} from "react";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import {useGetAppointmentsQuery} from "../../../../../Api/appointmentsApi.js";
|
import {useGetAppointmentsQuery} from "../../../../../Api/appointmentsApi.js";
|
||||||
@ -8,9 +8,9 @@ import {Grid} from "antd";
|
|||||||
|
|
||||||
const {useBreakpoint} = Grid;
|
const {useBreakpoint} = Grid;
|
||||||
|
|
||||||
const useAppointmentFormModalUI = (onCancel, createAppointment, patients) => {
|
const useAppointmentFormModalUI = (onCancel, createAppointment, patients, cancelAppointment) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const {modalVisible} = useSelector(state => state.appointmentsUI);
|
const {modalVisible, scheduledData} = useSelector(state => state.appointmentsUI);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const screens = useBreakpoint();
|
const screens = useBreakpoint();
|
||||||
|
|
||||||
@ -53,11 +53,24 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients) => {
|
|||||||
setSearchPatientString("");
|
setSearchPatientString("");
|
||||||
setFormValues({});
|
setFormValues({});
|
||||||
|
|
||||||
form.setFieldsValue({
|
if (scheduledData) {
|
||||||
appointment_datetime: dayjs(new Date()),
|
const patient = patients.find(p => p.id === scheduledData.patient_id);
|
||||||
})
|
if (patient) {
|
||||||
|
setSelectedPatient(patient);
|
||||||
|
setCurrentStep(1); // Skip to appointment details step
|
||||||
|
form.setFieldsValue({
|
||||||
|
patient_id: scheduledData.patient_id,
|
||||||
|
type_id: scheduledData.type_id,
|
||||||
|
appointment_datetime: dayjs(scheduledData.appointment_datetime),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
form.setFieldsValue({
|
||||||
|
appointment_datetime: dayjs(new Date()),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [modalVisible, form]);
|
}, [modalVisible, form, scheduledData, patients]);
|
||||||
|
|
||||||
const handleResultsChange = (newContent) => {
|
const handleResultsChange = (newContent) => {
|
||||||
setResults(newContent);
|
setResults(newContent);
|
||||||
@ -144,8 +157,13 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients) => {
|
|||||||
results: results,
|
results: results,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
await createAppointment(data).unwrap();
|
await createAppointment(data).unwrap();
|
||||||
|
|
||||||
|
if (scheduledData) {
|
||||||
|
await cancelScheduledAppointment(scheduledData.id);
|
||||||
|
dispatch(setSelectedScheduledAppointment(null));
|
||||||
|
}
|
||||||
|
|
||||||
notification.success({
|
notification.success({
|
||||||
message: 'Прием создан',
|
message: 'Прием создан',
|
||||||
description: 'Прием успешно создан.',
|
description: 'Прием успешно создан.',
|
||||||
@ -166,6 +184,18 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, patients) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const cancelScheduledAppointment = async (selectedScheduledAppointmentId) => {
|
||||||
|
try {
|
||||||
|
await cancelAppointment(selectedScheduledAppointmentId);
|
||||||
|
} catch (error) {
|
||||||
|
notification.error({
|
||||||
|
message: 'Ошибка',
|
||||||
|
description: error.data?.message || 'Не удалось отменить прием.',
|
||||||
|
placement: 'topRight',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
setSelectedPatient(null);
|
setSelectedPatient(null);
|
||||||
|
|||||||
@ -25,14 +25,16 @@ const useScheduledAppointmentFormModalUI = (patients, createScheduledAppointment
|
|||||||
type_id: selectedAppointmentType
|
type_id: selectedAppointmentType
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(data)
|
|
||||||
|
|
||||||
await createScheduledAppointment(data).unwrap();
|
await createScheduledAppointment(data).unwrap();
|
||||||
notification.success({
|
notification.success({
|
||||||
message: 'Прием создан',
|
message: 'Прием создан',
|
||||||
placement: 'topRight',
|
placement: 'topRight',
|
||||||
description: 'Прием успешно запланирован.',
|
description: 'Прием успешно запланирован.',
|
||||||
})
|
});
|
||||||
|
|
||||||
|
setSelectedPatient(null);
|
||||||
|
setSelectedDateTime(dayjs(new Date()).add(1, 'day'));
|
||||||
|
setSelectedAppointmentType(null);
|
||||||
|
|
||||||
dispatch(closeScheduledModal());
|
dispatch(closeScheduledModal());
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -2,8 +2,11 @@ import {Button, Modal, Popconfirm, Row, Typography} from "antd";
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import useScheduledAppointmentsViewModal from "./useScheduledAppointmentsViewModal.js";
|
import useScheduledAppointmentsViewModal from "./useScheduledAppointmentsViewModal.js";
|
||||||
import useScheduledAppointmentsViewModalUI from "./useScheduledAppointmentsViewModalUI.js";
|
import useScheduledAppointmentsViewModalUI from "./useScheduledAppointmentsViewModalUI.js";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import {openModalWithScheduledData} from "../../../../../Redux/Slices/appointmentsSlice.js";
|
||||||
|
|
||||||
const ScheduledAppointmentsViewModal = () => {
|
const ScheduledAppointmentsViewModal = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
const scheduledAppointmentsViewModalData = useScheduledAppointmentsViewModal();
|
const scheduledAppointmentsViewModalData = useScheduledAppointmentsViewModal();
|
||||||
const scheduledAppointmentsViewModalUI = useScheduledAppointmentsViewModalUI(scheduledAppointmentsViewModalData.cancelAppointment);
|
const scheduledAppointmentsViewModalUI = useScheduledAppointmentsViewModalUI(scheduledAppointmentsViewModalData.cancelAppointment);
|
||||||
|
|
||||||
@ -11,6 +14,15 @@ const ScheduledAppointmentsViewModal = () => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleConvertToAppointment = () => {
|
||||||
|
dispatch(openModalWithScheduledData({
|
||||||
|
id: scheduledAppointmentsViewModalUI.selectedScheduledAppointment.id,
|
||||||
|
patient_id: scheduledAppointmentsViewModalUI.selectedScheduledAppointment.patient?.id,
|
||||||
|
type_id: scheduledAppointmentsViewModalUI.selectedScheduledAppointment.type?.id,
|
||||||
|
appointment_datetime: scheduledAppointmentsViewModalUI.selectedScheduledAppointment.scheduled_datetime,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title="Просмотр запланированного приема"
|
title="Просмотр запланированного приема"
|
||||||
@ -51,6 +63,9 @@ const ScheduledAppointmentsViewModal = () => {
|
|||||||
onClick={scheduledAppointmentsViewModalUI.onCancel}>
|
onClick={scheduledAppointmentsViewModalUI.onCancel}>
|
||||||
Закрыть
|
Закрыть
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button type="primary" onClick={handleConvertToAppointment}>
|
||||||
|
Конвертировать в прием
|
||||||
|
</Button>
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title="Вы уверены, что хотите отменить прием?"
|
title="Вы уверены, что хотите отменить прием?"
|
||||||
onConfirm={scheduledAppointmentsViewModalUI.cancelScheduledAppointment}
|
onConfirm={scheduledAppointmentsViewModalUI.cancelScheduledAppointment}
|
||||||
@ -62,7 +77,6 @@ const ScheduledAppointmentsViewModal = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,72 +1,69 @@
|
|||||||
import { createSlice } from "@reduxjs/toolkit";
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
collapsed: true,
|
|
||||||
siderWidth: 250,
|
|
||||||
hovered: false,
|
|
||||||
modalVisible: false,
|
modalVisible: false,
|
||||||
scheduledModalVisible: false,
|
collapsed: true,
|
||||||
|
siderWidth: 300,
|
||||||
|
hovered: false,
|
||||||
selectedAppointment: null,
|
selectedAppointment: null,
|
||||||
scheduledAppointments: [],
|
|
||||||
selectedScheduledAppointment: null,
|
selectedScheduledAppointment: null,
|
||||||
|
scheduledModalVisible: false,
|
||||||
|
scheduledData: null,
|
||||||
|
selectedAppointments: [], // Новое поле для хранения массива выбранных приемов
|
||||||
};
|
};
|
||||||
|
|
||||||
const appointmentsSlice = createSlice({
|
const appointmentsSlice = createSlice({
|
||||||
name: 'appointmentsUI',
|
name: 'appointmentsUI',
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
toggleSider: (state) => {
|
openModal(state) {
|
||||||
state.collapsed = !state.collapsed;
|
|
||||||
},
|
|
||||||
setSiderWidth: (state, action) => {
|
|
||||||
state.siderWidth = action.payload;
|
|
||||||
},
|
|
||||||
setHovered: (state, action) => {
|
|
||||||
state.hovered = action.payload;
|
|
||||||
},
|
|
||||||
setSelectedDate: (state, action) => {
|
|
||||||
state.selectedDate = action.payload;
|
|
||||||
},
|
|
||||||
openModal: (state) => {
|
|
||||||
state.modalVisible = true;
|
state.modalVisible = true;
|
||||||
},
|
},
|
||||||
closeModal: (state) => {
|
closeModal(state) {
|
||||||
state.modalVisible = false;
|
state.modalVisible = false;
|
||||||
},
|
},
|
||||||
openScheduledModal: (state) => {
|
toggleSider(state) {
|
||||||
state.scheduledModalVisible = true;
|
state.collapsed = !state.collapsed;
|
||||||
},
|
},
|
||||||
closeScheduledModal: (state) => {
|
setSiderWidth(state, action) {
|
||||||
state.scheduledModalVisible = false;
|
state.siderWidth = action.payload;
|
||||||
},
|
},
|
||||||
setSelectedAppointments: (state, action) => {
|
setHovered(state, action) {
|
||||||
state.selectedAppointments = action.payload;
|
state.hovered = action.payload;
|
||||||
},
|
},
|
||||||
setSelectedAppointment: (state, action) => {
|
setSelectedAppointment(state, action) {
|
||||||
state.selectedAppointment = action.payload;
|
state.selectedAppointment = action.payload;
|
||||||
},
|
},
|
||||||
setScheduledAppointments: (state, action) => {
|
setSelectedScheduledAppointment(state, action) {
|
||||||
state.scheduledAppointments = action.payload;
|
|
||||||
},
|
|
||||||
setSelectedScheduledAppointment: (state, action) => {
|
|
||||||
state.selectedScheduledAppointment = action.payload;
|
state.selectedScheduledAppointment = action.payload;
|
||||||
},
|
},
|
||||||
}
|
openScheduledModal(state) {
|
||||||
|
state.scheduledModalVisible = true;
|
||||||
|
},
|
||||||
|
closeScheduledModal(state) {
|
||||||
|
state.scheduledModalVisible = false;
|
||||||
|
},
|
||||||
|
openModalWithScheduledData(state, action) {
|
||||||
|
state.modalVisible = true;
|
||||||
|
state.scheduledData = action.payload;
|
||||||
|
},
|
||||||
|
setSelectedAppointments(state, action) {
|
||||||
|
state.selectedAppointments = action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const {
|
export const {
|
||||||
toggleSider,
|
|
||||||
setSiderWidth,
|
|
||||||
setHovered,
|
|
||||||
setSelectedDate,
|
|
||||||
openModal,
|
openModal,
|
||||||
closeModal,
|
closeModal,
|
||||||
setSelectedAppointments,
|
toggleSider,
|
||||||
|
setHovered,
|
||||||
setSelectedAppointment,
|
setSelectedAppointment,
|
||||||
setSelectedScheduledAppointment,
|
setSelectedScheduledAppointment,
|
||||||
setScheduledAppointments,
|
|
||||||
openScheduledModal,
|
openScheduledModal,
|
||||||
closeScheduledModal,
|
closeScheduledModal,
|
||||||
|
openModalWithScheduledData,
|
||||||
|
setSelectedAppointments,
|
||||||
} = appointmentsSlice.actions;
|
} = appointmentsSlice.actions;
|
||||||
|
|
||||||
export default appointmentsSlice.reducer;
|
export default appointmentsSlice.reducer;
|
||||||
Loading…
x
Reference in New Issue
Block a user